Linux
nohup
コマンドを使用すると、重要なプロセスを起動した端末ウィンドウが閉じている場合でも、重要なプロセスを実行し続けることができます。この由緒あるコマンドを今日の Linux で使用する方法を説明します。
ハッとため息
Linux の祖先である Unix は 、PC が発明される前に作成されました。コンピューターは大きくて高価な機器でした。人々は、同じ建物内でローカルに、または低速モデム接続を介してリモートで、シリアル回線を介してそれらと対話しました。当初、彼らは テレプリンターで指示を入力していましたが、徐々にダム端末に置き換えられました 。
処理能力が入力している端末ではなく、接続されているコンピュータにあるため、それらはダムと呼ばれていました。プログラムは、机の上のデバイスではなく、コンピューター上で実行されていました。それがどこにあったとしてもです。
端末とコンピュータ間の接続が切断される何かが発生した場合、コンピュータは回線切断を検出し、実行していたプログラムに
HUP
またはハングアップ信号を送信します。プログラムはシグナルを受信すると実行を停止しました。
その機能は今日の Linux にも生き続けています。 PC では、 ターミナル ウィンドウは 物理ターミナルのエミュレーションです。そのターミナル ウィンドウから起動されたプロセスが実行されている場合、そのウィンドウを閉じると、SIGHUP
信号がプログラムに送信され、プログラムに HUP が通知され、 終了する 必要があることがわかります。
カスケード効果が起こります。プロセスが子プロセスを起動している場合、SIGHUP も子プロセスに渡され、終了する必要があることがプロセスに通知されます。
nohup
コマンドは子プロセスを起動しますが、子プロセスに SIGHUP シグナルを渡すことを拒否します。面倒そうに聞こえるかもしれませんが、実は便利な機能なのです。
nohup コマンド
プロセスの起動元のターミナル ウィンドウが閉じられた場合でもプロセスを続行させたい場合は、プログラムが SIGHUP を受信しないように SIGHUP をインターセプトする方法が必要です。 (実際には、ターミナル ウィンドウはプロセスを起動しません。プロセスはターミナル ウィンドウ内のシェル セッションによって起動されます。) この問題に対するシンプルかつ洗練された解決策は、シェル セッションとプログラムの間に別のプロセスを配置し、それを実行することです。中間層プログラムは SIGHUP シグナルを渡しません。
それが
nohup
のやっていることです。シェルの子プロセスではなく、
nohup
の子プロセスになるようにプログラムを起動します。これらはシェルの子プロセスではないため、シェルから SIGHUP を直接受け取りません。また、
nohup
SIGHUP をその子に渡さない場合、プログラムは SIGHUP をまったく受け取りません。
これは、たとえば、長時間実行されるプロセスを最後まで実行する必要がある場合に便利です。誤ってターミナル ウィンドウとそのシェルを閉じてしまうと、プロセスも終了してしまいます。
nohup
を使用してプロセスを起動すると、プロセスが
nohup
信号から分離されます。
SSH 経由で
コンピュータ上でリモート作業していて、リモート接続が失敗した場合に機密プロセスが終了したくない場合は、
nohup
を使用してリモート コンピュータ上でプロセスを開始します。
nohupの使用
何も役に立たないプログラムを作成しましたが、終了するまで実行され続けます。ターミナル ウィンドウに 3 秒ごとに時刻を出力します。 「長いプロセス」という意味で、long-proc と呼ばれます。
./long-proc
これが何か役に立つことを行うプログラムで、ターミナル ウィンドウとシェルが閉じても実行し続けたい場合は、
nohup
を使用して起動します。
nohup ./long-proc
このプロセスは
stdin
と
stdout
から切り離されているため、入力を受け取ったり、ターミナル ウィンドウに書き込んだりすることはできません。また、まだ実行中であるため、コマンド プロンプトには戻りません。
nohup
が行うことは、プロセスがターミナルの終了の影響を受けないようにすることだけです。
プロセスがバックグラウンド タスクになる
わけではありません。
プロセスを終了するためだけに
再起動する
必要がありますか?いいえ。バックグラウンド プロセスとして起動していない
nohup
プロセスを停止するには、Ctrl+C キーの組み合わせを押します。
プログラムからの出力は、「nohup.out」というファイルにキャプチャされています。少ない量でレビューできます。
nohup.out を減らす
通常端末ウィンドウに送信されるものはすべてファイルにキャプチャされます。以降の
nohup
の実行は、既存の「nohup.out」ファイルに追加されます。
プロセスを実行するより便利な方法は、ターミナル ウィンドウが閉じられても耐えられるように
nohup
を使用してプロセスを起動し、同時にプロセスを
バックグラウンド タスク
にすることです。これを行うには、コマンドラインの末尾にアンパサンド「
&
」を追加します。
nohup ./long-proc &
コマンド プロンプトに戻るには、もう一度「Enter」を押す必要があります。プロセスのジョブ番号は 1 — 括弧 ”
[]
” — であり、プロセス ID は 13115 であることがわかります。
これらのいずれかを使用してプロセスを終了できます。プログラムはターミナル ウィンドウまたはシェルのいずれにも関連付けられていないため、「Ctrl+C」は機能しません。
ジョブ番号を忘れた場合は、
jobs
コマンドを使用して、その端末ウィンドウから起動されたバックグラウンド タスクを一覧表示できます。
仕事
タスクを強制終了するには、次のように、
kill
コマンドとジョブ番号の前にパーセント記号「
%
」を付けて使用します。
%1を殺す
ターミナル ウィンドウを閉じた場合は、プロセス ID を見つけて、それを
kill
コマンドで使用する必要があります。
pgrep
コマンドは、指定した検索手がかりに一致するプロセスのプロセス ID を見つけます。プロセス名を検索してみます。
pgrep ロングプロシージャ
これで、プロセス ID を使用してプロセスを終了できるようになりました。
13115を殺す
次回「Enter」を押すと、プロセスが終了したことが通知されます。
次に、何がプロセスを終了させないのかを見てみましょう。再起動して、ターミナル ウィンドウを閉じます。
nohup ./long-proc
新しいターミナル ウィンドウを開いて
pgrep
でプロセスを検索すると、プロセスがまだ実行中であることがわかります。プロセスを起動したターミナル ウィンドウを閉じても効果はありません。
pgrep ロングプロシージャ
複数のコマンドを
nohup
に渡すことは可能ですが、通常は個別に起動することをお勧めします。これにより、バックグラウンド ジョブとして操作することが容易になります。コマンドは同時に実行されるのではなく、順番に実行されます。実行は同時実行ではなく、順次実行されます。これらを同時に実行するには、それらを個別に起動する必要があります。
ただし、
複数のプロセスを一度に起動する
には、
nohup
を使用して Bash シェルを起動し、コマンド文字列で
-c
(コマンド) オプションを使用します。コマンド リストを囲むには一重引用符「
'
」を使用し、コマンドを区切るには二重アンパサンド「
&&
」を使用します。
nohup bash -c 'ls /bin && ls /sbin'
「nohup.out」ファイルを参照するために
less
使用する
と、最初のプロセスからの出力が表示され、次に2番目のプロセスからの出力が表示されます。
nohup.out を減らす
両方のコマンドの出力は、「nohup.out」ファイルにキャプチャされています。これは絡み合っておらず、最初のプロセスが終了した後にのみ 2 番目のプロセスからの出力が開始されます。
「nohup.out」の代わりに独自のファイルを使用したい場合は、 コマンドを選択したファイルにリダイレクト できます。
nohup bash -c 'ls /bin && ls /sbin' > myfile.txt
メッセージは「出力を nohupo.out に追加」ではなく、「stderr を stdout にリダイレクト」と表示され、stdout を「myfile.txt」ファイルにリダイレクトしていることに注意してください。
「myfile.txt」ファイル内をlessで見ることができます。
myfile.txt を減らす
前と同様に、両方のコマンドの出力が含まれています。
面白いのは、ユーティリティの歴史を振り返ると、それが現代とは何の関連性もないかのように見えることがあるということです。
nohup
コマンドも
その 1 つです。シリアル回線の切断に対処するために作成されたものは、信じられないほど強力なマシンを使用する今日の Linux ユーザーにとって依然として役立ちます。





