連載
» 2017年08月24日 05時00分 公開

Linux基本コマンドTips(137):【 nohup 】コマンド――端末を閉じてもログアウトしても処理を続ける

本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、端末を閉じたりログアウトしたりしても処理を続行させるための「nohup」コマンドです。

[西村めぐみ,@IT]
「Linux基本コマンドTips」のインデックス

Linux基本コマンドTips一覧

 本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、端末を閉じたりログアウトしたりしても処理を続行させるための「nohup」コマンドです。

nohupコマンドとは?

 コマンドを実行している際に、仮想端末(Terminal)の画面を閉じたりログアウトしたりすると、実行中のコマンドも終了してしまいます(コマンドをバックグラウンド実行していても終了する)。

 コマンド起動時に「nohup コマンド &」と指定することで、このような場合でもそのままコマンドの実行を続けることができます。

 例えば、リモート先で時間のかかる処理を始めたい場合に、「sshでログインし、nohup付きでコマンドを実行し、ログアウトする」という形で活用します。



nohupコマンドの書式

nohup コマンド [引数] &

※[ ]は省略可能な引数を示しています。





nohupの主なオプション

 nohupには動作オプションがありません。ヘルプを表示する「--help」と、バージョンを表示する「--version」のみ使用できます。



nohupコマンドの使いどころ

 コマンドを実行している際に、仮想端末を閉じたりログアウトしたりすると、そのシェルで実行中のプロセスにはHUPシグナル(SIGHUP:制御している端末の終了を伝えるシグナル)が送られます ※1。

※1 シグナルについては、「“応用力”をつけるためのLinux再入門」の第16回を参照。



 「nohup コマンド &」のようにnohupを付けてコマンドを実行すると、このHUPシグナルを無視させます。つまり、仮想端末を閉じたりログアウトしたりしても、コマンドは終了せず、そのまま処理を続行します。

 例えば、「rsync -a ~ /mnt/0825/」を実行してすぐログアウトしたいが、最後までrsyncの処理を続けて欲しい、というような場合には「nohup rsync -a ~ /mnt/0825/ &」のように実行します ※2。

 仮想端末を閉じてしまいますから、コマンドからの出力をファイルに保存する仕組みが用意されています。まずはカレントディレクトリの「nohup.out」に保存を試み、ファイルを作成できない場合は、ホームディレクトリにnohup.outを作成します。他のファイル名で保存したい場合は、「nohup コマンド > ファイル名 &」のようにリダイレクトを指定した上でコマンドを実行するとよいでしょう。

※2 rsyncはディレクトリの同期を行うコマンド(第82回第83回)。「rsync -a ~ /mnt/0824/」は自分のホームディレクトリを、/mntにマウントしたディスクの/0824ディレクトリ下にコピーするという意味。今回の例ではバックグラウンドで実行するという前提があるため、メッセージを出力していない。実行中の処理内容を出力したい場合は「-v」オプションを併用する。


コマンド実行例

nohup コマンド &

nohup rsync -a ~ /mnt/0824/ &




nohupコマンドの動作を試す

 以下では、「ping」コマンドを使ってnohupコマンドの動作を試しています。pingはサーバやIPアドレスを指定して、ネットワーク経由で応答の有無を調べるコマンドです。今回は対象を“localhost”、つまり自分自身に選び、単に“1秒ごとの結果を1行ずつ出力し続けるコマンド”として使用しています。

 まず仮想端末の画面を2つ開きます。画面1では、比較用に「ping localhost >/dev/null &」を実行してから、「nohup ping localhost &」を実行しています。

画面1 画面1 2つのpingコマンドを実行してnohupの動作を調べる(準備)

 画面2では、「ps」コマンドでpingの実行の様子を確認します。

 「ps -o pid,ppid,stat,tt,user,cmd -p `pidof ping`」の「-o」は出力内容を指定するオプションで、ここでは、プロセスID(pid)と親プロセスのID(ppid)、状態(stat)、端末(tt)、ユーザー(user)、コマンド列(cmd)を指定しています。

 「-p」は表示するプロセスIDを指定するオプションで、「pidof ping」でpingのプロセスIDを指定しています。「pidof」は指定した名前のプロセスIDを返すコマンドです。

画面2 画面2 nohupコマンドの効果を確認しているところ

 psコマンドでプロセスID「3504」と「3509」という2つのプロセスが動いていることを確認した後、画面1の端末ウィンドウを閉じます ※3。

※3 端末ウィンドウを「bash」の組み込みコマンド「exit」を使って終了した場合、HUPシグナルは送られない。そのため、画面1のどちらのpingコマンドも実行を続ける。exit実行時にHUPシグナルを送るよう設定するにはbashの組み込みコマンド「shopt」を使う。shoptでhuponexitを有効にすると、bash終了時に全てのジョブに対してHUPシグナルを送信する。



 再度psコマンドで確認すると、「3509」だけが残っています。親プロセス(bash)が終了したため親プロセス(PPID)が「1」に、端末(TT)から切り離されたので「?」となっていることが分かります。

 pingの出力ファイルを調べてみましょう。「tail」コマンドで「nohup.out」を確認すると、実行結果が追加されていることが分かります。pingコマンドは1秒置きに結果を出力するので、1秒以上空けてtailコマンドを実行し、内容が変わっていることを確認しています。

 pingは「-c」オプションで実行回数を指定しなかった場合、[CTRL]+[C]を入力するまで実行を続けます。画面1でpingを起動したシェルは既に終了しており、pingコマンドを終了させることができません。そこで、最後に「killall ping」でpingを終了しています。



nohupやバックグラウンド指定を忘れた場合に対処する

 nohupを忘れて実行した場合や、「&」を付けるのを忘れてしまった場合は、[CTRL]+[Z]で中断し、「bg」コマンドで再開させてから、「disown」コマンドを実行します。

 「disown」はシェルのビルトインコマンドで、現在のシェルが管理しているジョブテーブルからカレントのジョブを削除します。disownコマンドを実行することで、シェルが終了してもコマンドが続行されることになります ※4。

※4 ジョブについては、「“応用力”をつけるためのLinux再入門」の第15回を参照。



 なお、「disown %1」のように、削除するジョブの番号を指定したり、「disown -a」で全てのジョブを削除したりできます。削除したジョブは「jobs」コマンドで表示したり、「fg」「bg」でコントロールしたりできなくなります。

 ジョブテーブルに残したままにしたい場合は「-h」オプションを付けて実行します。「-h」はHUPシグナルを送る対象から外す、という意味のオプションです。

 画面3では、先ほどと同様、pingコマンドを使って動作を試しています。実行内容を見やすくするため「-i」オプションで、メッセージの表示間隔を10秒としています。画面4では、画面3で実行しているpingの様子をpsコマンドで確認しています。

画面3 画面3 実行したpingコマンドを端末を閉じても終了しないように後から設定しているところ
画面4 画面4 pingコマンドの動作を確認しているところ


筆者紹介

西村 めぐみ(にしむら めぐみ)

PC-9801NからのDOSユーザー。PC-486DX時代にDOS版UNIX-like toolsを経てLinuxへ。1992年より生産管理のパッケージソフトウェアの開発およびサポート業務を担当。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『はじめてでもわかるSQLとデータ設計』『シェルの基本テクニック』など。2011年より、地方自治体の在宅就業支援事業にてPC基礎およびMicrosoft Office関連の教材作成およびeラーニング指導を担当。


Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。