nohupコマンドを使うことでターミナルを閉じてもバッチ処理(コマンド)を実行し続けることができます。
下のブログ記事が参考になるというか、何なら実行するには充分だと思います。
本記事ではnohupコマンドってなんだ?みたいな自分が疑問に思って調べたことを追記しておきます。
[Linux] Terminalを閉じてもバックグラウンドの処理を実行し続ける - nohup
nohupコマンドの使い道
nohupコマンドの使い道については先のブログでわかりやすかったので引用します。
Linuxでシステム運用をしていると、数時間〜数日間に及ぶバッチ処理を実行することがあります。手動でプログラムを起動する場合にディスプレイの前にずっと付きっきりでは過労死まっしぐらです。またうっかりTerminalを閉じてしまうと大惨事になってしまうため通常はバックグラウンドで実行します。
これに加えて、実例としてAWS Systems Manager Session Managerを使ってAWS EC2インスタンスに接続したとき、長時間操作がなかったり、サインインセッションが切れたりするとターミナルが閉じてしまいます。
何らかの原因でターミナルが閉じてしまうとコマンドが停止してしまうので、それを防ぐためにnohupコマンドを使います。
試した環境
以下ではLinuxコマンドを使って試しています。 利用した環境は以下のとおりです・
nohupコマンドの使い方
以下のように使います。
$ nohup {実行し続けたいコマンド} &
末尾の&
は実行し続けたいコマンドをバックグラウンドで実行させることを意味します。バックグラウンドで実行していてもターミナルが閉じられると処理は停止してしまいます。
先頭のnohup
によって、ターミナルが閉じても処理を停止しないようになります。
標準出力への出力はコマンドを実行したディレクトリにnohup.out
というファイルが作成され、そこに追記されていきます。
標準エラー出力は標準出力にリダイレクトされているため、nohup.out
に追記されます。
実際の例を見てみます。
sleepコマンドは指定された秒数だけ待機するコマンドのため、$ sleep 10
というようにターミナルでそのまま実行すると10秒後にプロンプトが返ってきます。
以下のように実施すると、バックグラウンドで実行されるため、プロンプトはすぐに返ってきます。
また、現在のディレクトリにnohup.out
というファイルが作成されているはずです(標準出力される内容が存在しないため、空ファイルです)。
$ nohup sleep 10 &
出力先をnohup.outから別のファイルにする
方法は、manコマンドに書かれており、リダイレクトでファイル名を指定するだけです。
To save output to FILE, use 'nohup COMMAND > FILE'.
$ nohup {実行し続けたいコマンド} > {出力先ファイル} &
実例で試してみます。sleepコマンドだけでは標準出力に何も出てこないのでechoを使って確認してみます。
mycommand.sh
というファイルを作成し、以下の内容を記述しておきます。
このスクリプトファイルが実行されると、start
と現在日時が出力され、5秒後にfin
と現在日時が出力されます。
#!/bin/bash echo 'start' `date` sleep 5 echo 'fin' `date`
nohupコマンドでこのスクリプトファイルを実行してみます。
$ nohup sh ./mycommand.sh &
カレントディレクトリにnohup.outが作成され、以下のようになっています。
start Fri Aug 10 00:00:01 JST 2023 fin Fri Aug 10 00:00:06 JST 2023
同じコマンドを再度実行すると、nohup.outに追記されます。
start Fri Aug 10 00:00:01 JST 2023 fin Fri Aug 10 00:00:06 JST 2023 start Fri Aug 10 00:14:24 JST 2023 fin Fri Aug 10 00:14:29 JST 2023
一度nohup.outを削除し、出力先ファイルをmyout.outに変更してみます。
$ nohup sh ./mycommand.sh > myout.out &
カレントディレクトリを確認してみると、nohup.outは存在していません。代わりにmyout.outが作成されています。 内容は先程のnohup.outと同じようになります。
start Fri Aug 10 00:23:36 JST 2023 fin Fri Aug 10 00:23:41 JST 2023
バックグラウンドで実行されている処理(コマンド、ジョブ)を確認する
&
を使うことでコマンドをバックグラウンドで実行できることは既に紹介しています。
ここではバックグラウンドで実行されている処理がいくつあるのかを確認するjobs
コマンドを見ていきます。
$ nohup sleep 10 & $ jobs [1]+ Running nohup sleep 10 &
jobsコマンドによってジョブ一覧が表示され、それぞれのジョブ番号と実行状態と処理の内容が確認できます。
ジョブとプロセス
『新しいLinuxの教科書』によれば、
ということであり、今回ジョブの一覧を見るにはjobsコマンドが使えます。
バックグラウンドからフォアグラウンドに戻す
実行したジョブを途中で停止したいときや、シェルを使って対話的に操作したいときには、ジョブをバックグラウンドからフォアグラウンドに戻します。
このときにはfg
コマンドを使います。fgコマンドはjobsコマンドで見たジョブ番号を使います。
$ fg {ジョブ番号}
もしくは
$ fg %{ジョブ番号}
実際の例です。
$ nohup sleep 30 & $ jobs [1]+ Running nohup sleep 30 & $ fg 1 nohup sleep 30
フォアグラウンドからバックグラウンドに戻す
今度は逆にジョブをフォアグラウンドからバックグラウンドに戻します。
使うコマンドはbg
コマンドです。使い方はfgコマンドと同じです。
$ bg {ジョブ番号}
もしくは
$ bg %{ジョブ番号}
実際の例です。
nohupコマンドをバックグラウンドで実行し、fgコマンドでフォアグラウンドに戻します。Ctrl + Z(^Z
の部分)でジョブを停止し、bgコマンドでバックグラウンドで処理を再開させます。
$ nohup sleep 30 & $ jobs [1]+ Running nohup sleep 30 & $ fg 1 nohup sleep 30 ^Z $ jobs [1]+ Stopped nohup sleep 30 & $ bg 1
nohupはSIGHUPを受け付けないという意味
ターミナルが終了するさいに、ジョブはSIGHUP(ハングアップ、Hang up)というシグナルを受け取って終了します。
nohupはこのSIGHUPを受け取っても停止しないようにするためのコマンドです。
NO Hang UPで覚えれば忘れないはず。