バックグラウンドプロセス(ジョブ)の管理
ログインして対話的に使う分にはなんら問題はないのですが、ずっと動かしっぱなしのプロセスはどうするのかな、という疑問が出てきました。動かしてるプロセス分ターミナルを立ち上げてるというのも現実的じゃないし、screen で複数プロセス動かすのもありかもしれないけど、ちょっと違うような気がするし、そもそもログアウトしてプロセスがなくなっちゃったらまずいし。ということで、自分のやりたいことを念頭において調べてみました。
※ 以下の説明では、バックグラウンドプロセスのことを「ジョブ」と書くことがあります。
まとめ
- & コマンドラインの最後に'&'を付けるとバックグラウンドで起動
- jobs いま動いているバックグラウンドプロセスの一覧を表示
- fg バックグラウンドプロセスをフォアグラウンドへ移す
- bg バックグラウンドプロセスを実行する
- kill バックグラウンドプロセスを強制終了させる
- Ctrl+Z プロセスの中断(バックグラウンドに限らず有効)
バックグラウンドプロセスとして実行
コマンドラインの最後に '&' を付けるとバックグラウンドでの実行になります。
$ cat > xxx &
[1] 27479
$
[1]+ Stopped cat > xxx
[1]はジョブ番号、27479はプロセスIDです。ジョブ番号を指定するときは %1 で、プロセスIDはそのまま使えます。
プロンプトは出ていませんが、この状態でもうバックグラウンドで「cat > xxx」プロセスが走って、フォアグランドに戻ってきています。試しに la してみると、0バイトで xxx というファイルができています。
[1]+ Stopped cat > xxx
la
total 84
drwxr-xr-x 7 mam 4096 2008-06-09 05:49 ./
drwxr-xr-x 9 root 4096 2008-04-29 06:18 ../
-rw-r--r-- 1 mam 0 2008-06-09 05:49 xxx
あと1つ、「cat > yyy &」もバックグラウンドで走らせてみます。
バックグラウンドプロセスの確認
$ jobs
[1]- Stopped cat > xxx
[2]+ Stopped cat > yyy
jobs でバックグラウンドで実行(停止)中のプロセスの一覧が表示されます。"+"はカレント・ジョブ、"-"は前のジョブです。それより前のジョブのこの欄は空白です。
バックグラウンドプロセスをフォアグラウンドへ
$ fg
cat > yyy
fg でカレント・ジョブをフォアグラウンドへもってきます。「cat > yyy」へ実行が移りました。文字を入力すると、それが yyy へ書き込まれます。プロセスを中断するには Ctrl+Z を入力します。
cat > yyy
← ここで Ctrl+Z を入力
[2]+ Stopped cat > yyy
$
バックグラウンドプロセスを実行する
cat の例だとわかりづらいので新しい例で説明します。
$ sleep 10 ← ここで Ctrl+Z を入力 [1]+ Stopped sleep 10 $ bg %1 [1]+ sleep 10 & $ jobs [1]+ Running sleep 10 & $ [1]+ Done sleep 10
フォアグラウンドで動かした「sleep 10」を Ctrl+Z で中断します。この時点で中断されたプロセスは、Stopped 状態のバックグラウンドプロセスになります。
これを「bg %1」で実行(リスタート)すると、バックグラウンドプロセスのまま、Running 状態になります。「sleep 10」の実行が終了すると最後の行( Done )が返されます。
バックグラウンドプロセスの強制終了
kill でバックグラウンドプロセスを強制終了させることができます。
$ sleep 10 ← ここで Ctrl+Z を入力 [1]+ Stopped sleep 10 $ jobs -pl [1]+ 27765 Stopped sleep 10 $ kill %1 $[1]+ Terminated sleep 10 $ jobs $
bg では「bg %1」でも「bg 1」でも同じでしたが、kill はそういうわけにいきませんので要注意。
$ jobs -pl [1]+ 27765 Stopped sleep 10 [2]- 27767 Stopped sleep 20 $ kill 27765 $ kill 1 bash: kill: (1) - Operation not permitted $ kill %1 $[1]+ Terminated sleep 10 $ kill -9 27767 $[1]+ Killed sleep 20
ジョブ番号(%)を指定します。%を付けないと通常のプロセスIDでの killになってしまうので、思いもよらぬサービスを killしてしまわないように気をつけましょう。
プロセスIDを指定しても killできますが、Killシグナル( -9 )を付けないと 強制終了はできないようです。
プロセスの中断
Ctrl+Z でプロセスを中断できます。フォアグラウンドで実行中のプロセスを中断するとそのプロセスは自動的に Stopped 状態のバックグラウンドプロセスになります。
「stop %」でバックグラウンドプロセスの停止ができるはずですが、うちの環境では「stop: Need to be root」ということで停止できず、じゃあ「sudo stop %1」とかやると「stop: Unknown job: %1」と言われてやっぱり停止できず。fg して Ctrl+Z で停止できるので深いところまでは調査せず。
jobs [-lrs] [%jobid]
- -l プロセスIDも表示
- -r 実行中のジョブだけ表示
- -s 停止中のジョブだけ表示
- %jobid jobidで指定したジョブだけ表示
ログアウトしてもバックグラウンド ジョブを継続する方法
詳しくはこちら(→ログアウトしてもバックグラウンド ジョブを継続する方法)を見ていただくとして要点だけ。
$ nohup ./abc.sh > out.log 2> err.log < /dev/null &
SSH でログインしている場合は、標準出力、標準エラー出力をリダイレクトして、標準入力を閉じておく、ことだそうです。
ただ単に「$ nohup ./abc.sh &」としただけでも、標準出力、標準エラー出力に送られたデータは「プログラムを実行したディレクトリ」に nohup.out というファイル名で保存されるということですから、これからいろいろと試してみます。
参考
- こちら(→http://tonetsutomu.com/tone/linux/BasicOperation/JobControl.htm)が参考になりました。
- こちら(→【 jobs 】 実行中のジョブを表示する | 日経 xTECH(クロステック))も頼りにしています。
- こちら(→ログアウトしてもバックグラウンド ジョブを継続する方法)も参考になります。