本ページには広告・プロモーションが含まれています。
SSH 接続で時間の掛かるシェルスクリプトをバックグラウンドで走らせて帰りたいのに、SSH 接続を切るとジョブが死んでしまいます。SSH 接続に限らず目の前の OS からログアウトしたりターミナル エミュレータを終了しても同じ現象が起こります。
この症状は正常です。なぜなら、バックグラウンド ジョブを起動したプロセス(ログイン シェル)が子プロセスである該当のバックグラウンドジョブをハングアップ シグナル( HUP
)によって終了させるからです。
シェルスクリプトを起動した親プロセスは子プロセスの終了状態を監視しています。ですからログアウトして親プロセスであるシェルが終了すると子プロセスはゾンビ プロセスとなってしまうので親プロセスとなるシェル(ログインシェル)は子プロセスであるバックグラウンド ジョブを kill
( kill -HUP
) するのです。
ジョブを kill
されないようにするには nohup
コマンドを使います。nohup
コマンドは HUP
シグナルを無視するようにプログラムを実行します。また標準出力、標準エラー出力はファイルになります。STDOUT
, STDERR
に出力データがなくてもファイルは作成されます。
nohup
コマンドでバックグラウンドで走らせたいバッチ処理プログラムなどを実行すればログアウトしても kill
されないのでプロセスは継続しますから心置きなく家へ帰れます。nohup
コマンドは Linux 以外にも Unix 系の OS なら使えるでしょう。私は Mac OS X で確認しています。無ければ GNU の coreutils にあります。
$ nohup ./abc.sh &
abc.sh
の標準出力、標準エラー出力に送られたデータはプログラムを実行したディレクトリに nohup.out
というファイル名で保存される。プログラムを実行したディレクトリに書き込み権限が無ければ $HOME/nohup.out
に保存される。
$ nohup ./abc.sh > out.log &
abc.sh
の標準出力が out.log
になる。標準エラー出力は nohup.out
で保存先は例1と同様にプログラムを実行したディレクトリか $HOME
になる。
$ nohup ./abc.sh > out.log 2> err.log &
abc.sh
の標準出力が out.log
になる。標準エラー出力は err.log
です。
以上のようなコマンドを実行した後はログアウトして大丈夫です。心配なら再度ログインしてプロセスを確認してみましょう。
SSH でログインしている場合は3つの I/O ストリーム をリダイレクトしておきます。SSH 接続でバックグラウド ジョブを実行する場合、日常的に標準出力、標準エラー出力をリダイレクトしていると思いますがここで重要なのは標準入力を閉じておくことです。具体的には /dev/null
にします。
$ nohup ./abc.sh > out.log 2> err.log < /dev/null &
詳しいことは SSH Frequently Asked Questions をご覧下さい。
もうひとつ、nohup
は実行したプログラムを自動的にバックグラウンド ジョブにするものではありません。バックグラウンドで実行するなら &
を付けて実行するか bg
コマンドを使いましょう。
nohup
で実行中のプログラムを終了させるにはプロセスIDを調べて kill
コマンドで強制終了(kill -KILL
)します。
最終更新日: 2014年05月03日(土) / カテゴリー: Unix, Linux