Linuxでnohupコマンドを使用する方法
公開: 2022-06-25 Linux nohup
コマンドを使用すると、重要なプロセスを起動したターミナルウィンドウが閉じている場合でも、重要なプロセスを実行し続けることができます。 この由緒あるコマンドを今日のLinuxで使用する方法を紹介します。
HUPとSIGHUP
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 long-proc
これで、プロセスIDを使用してプロセスを終了できます。
13115を殺す
次に「Enter」を押すと、プロセスが終了したことが通知されます。
次に、プロセスを終了しないものを見てみましょう。 再起動して、ターミナルウィンドウを閉じます。
nohup ./long-proc
新しいターミナルウィンドウを開き、 pgrep
でプロセスを検索すると、まだ実行中であることがわかります。 プロセスを起動したターミナルウィンドウを閉じても効果はありません。
pgrep long-proc
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」ファイルの内部をより少ない量で調べることができます。
より少ないmyfile.txt
以前と同様に、両方のコマンドからの出力が含まれています。
ユーティリティの歴史が、現代とは無関係であるかのように見えることがあるのはおかしいです。 nohup
コマンドはその1つです。 シリアル回線での切断に対処するために作成されたものは、今日のLinuxユーザーにとって非常に強力なマシンでも役立ちます。
関連:知っておくべき37の重要なLinuxコマンド