はじめに
コマンドラインで(簡単に)forループを回したい、ということはよくあることかと思います。一方、(コマンド自体は単純であったとしても)ループなのですから(回数によってはものすごく)時間が掛かる可能性があり、(接続が切れたりして)端末が終了してしまってもnohupで処理は続けてほしいな、というのも人情でしょう。forもnohupもそれぞれ単体は難しいものではないですが、組み合わせて使うのにちょっと苦戦しました1ので、その時の記録です。あと、シェルはbashです。
また、恒例のお断りですが、この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。
for
たとえば10回繰り返すには以下のようにします。この辺りは皆さんご存じでしょう。
$ for i in {1..10}; do echo $i; done
1
2
3
4
5
6
7
8
9
10
nohup
端末が終了してもa.outに動いておいてもらいたい場合には以下のようにするでしょう。これももちろん皆さんよくご存じですね。
nohup ./a.out > output
組み合わせ
だがしかし、nohupとforを単純に組み合わせると以下のように上手く行きません。
$ nohup for i in {1..10}; do ./a.out; done > output
-bash: syntax error near unexpected token `do'
以下のようにすると、上手く行きます。
nohup bash -c 'for i in {1..10}; do ./a.out; done' > output
bashのmanを読んでもどうして上手く行ったかはよく分かりませんでした。''で囲まれた部分はまとまりなのなのだから単体のforの時のように処理してね、そのまとまりを処理するbashに対してのnohupだよ(forに対して直接ではないよ)、ということで上手く行っているのかな、と考えています。(合ってるかな。)
おわりに
forではなくwhileだったら同様の回避法に触れた記事がありました。またやってしまいました、車輪の再発明、、、orz
いや、whileではなくforなので厳密では再発明ではない!?(まあ、分かっている人にとっては再発明ですよねぇ。)
-
コマンドラインにこだわらず、スクリプトファイル書けばよかったのでは、と言われればその通りです。 ↩