batchとnohup
学校の CUDA サーバを自宅より使う学生より、「接続が Broken Pipeで切れるのどうすれば?」との質問があった。
原因は ssh で操作が何もない状態が続くと、セキュリティのために接続が切られるため。んで、.ssh/ssh_config でセッションの最大時間を延ばす設定あたりを説明したけど、「計算どのぐらいかかるの?」と聞くと「20時間かな…」。# さすが CUDA を使う卒研。
ssh のセッション延長の設定で20時間とかしちゃうと、ネットワークトラブルで通信が途中で切れたときに、サーバ側で「まだこの ssh 通信中だよね…」というプロセスが生き残る可能性があるので、あまり勧められる方法ではない。
こういう時には、処理を継続したままで、ログアウトするテクニックが必要。
通常は処理を起動して、ログアウトすると親プロセスにあたる sh が死ぬので、子プロセスが死んでしまう。
# このプロセスの原則があるから、Linux サーバで「訳の変わらんプロセスがあったら、『親を殺せ!!』が基本。」
プロセス確認の基本
((( 通常のプロセス全表示 ))) $ ps ax ((( 指定したコマンドのプロセス情報表示 ))) $ ps ax | grep コマンド名など ((( プロセスの起動引数を全部表示 ))) $ ps axl ((( 負荷の高い順にプロセス一覧を表示 ))) $ top ((( 指定したプロセスを停止 ))) $ kill -KILL プロセス番号
プロセスのバックグラウンド起動
((( プロセスをバックグラウンド起動 ))) $ コマンド... & # &がバックグラウンド起動の意味 ((( プロセスをバックグラウンドに変更 ))) $ コマンド... # フォアグランドでプロセスが動き出す ^Z (Ctrl-Z) # プロセスを一時停止 $ fg # 停止中のプロセスを再びフォアグラウンドで再起動 $ bg # 停止中のプロセスをバックグラウンドで再起動 $ jobs # 起動中の job を表示
上記で説明したコマンドは、login した shell の子プロセスになるため、たとえバックグラウンドで起動して「裏で動いている…プロセス」といえども、logout すると親プロセスが死ぬので、一緒に子プロセスも死んでしまう。
このため、起動するプロセスの親をシステムに代替わりしてもらって起動する nohup コマンドが使われる。
((( プロセスを No Hugup コマンドで起動 ))) $ nohup コマンド & # 出力はファイル保存される。 $ nohup コマンド > file.out & # 明示的にリダイレクトで表示保存先を指定 $ tail file.out # 保存しているファイルの末尾を表示
ただし nohup コマンドだと、プロセスが終了したかどうかわからない。こういう時は、batch コマンドが便利。ただし、batch コマンドはインストールされていない処理系が多い。(メールの設定が必要だから)
((( at パッケージのインストール ))) $ sudo apt-get install at # at(指定時間コマンド起動) # batch(バッチ処理起動) ((( batchの使い方 ))) $ batch at> コマンド at> ^D $ echo "コマンド" | batch
ただし batch は PATH が /bin/sh だけで起動するので、”python ほげ.py” とかで起動しても動かない場合あり。”/usr/bin/python ほげ.py” とかPATHを明記して起動するか、PATH=/usr/local/bin:/usr/bin:/bin なりの設定する処理を明記しないと動かない場合があるので要注意。
batch は、処理の出力結果はメールで送られてくる。結果を残すのなら、出力リダイレクトをしておく方がいい。