シェルの終了時にプロセスが停止しないようにするには、Nohup
またはscreen
を介してコマンドを起動できます。次のコマンドで既存のプロセスを取り消すこともできます。
mycommand
# Press CTRL-Z
bg
disown %1
ただし、これは現在のシェルからのみ起動できます。
別のシェル/ sshセッションを使用して同じことを実行したいと思います(コマンドはシェルAで起動されますが、シェルBで起動されます)。
別のシェルからプロセスをバックグラウンドで実行することは可能です:
# CTRL-Z can be done via
kill -20 PID (SIGSTP)
# bg can be done via
kill -18 PID (SIGCONT)
しかし、プロセスはまだ最初のシェルによって所有されています。プロセスを別のシェルから否認するにはどうすればよいですか?
Linux 4.15を使用しています
まあ、それはデバッガでふざけてシェルプログラムを実行しているプロセスの内部を突く準備ができている場合です。より具体的には、これはシェルプログラミングのレベルでは単純明快な方法では不可能です。
これは、disown
が、シェルプログラムが個々のシェルプロセスのメモリ空間に保持する「ジョブ」のリストに影響を与えるためです。
シェル(ジョブコントロールシェル、つまり)は、disown
によって忘れるように指示されるか、子プロセスが終了してシェルにwait()
edし、「ジョブ」の終了を報告しました。 disown
は、子プロセスの状態には影響しません。シェルの動作に影響します。
disown
edプロセスを忘れているため…
wait()
が子の終了について通知したときに、「ジョブ」の完了を認識しなくなりました。exit
/logout
に指示されたときにプロセスがまだ実行されているかどうかは問題ではなくなりました。そしてシェルはこれらのリストを共有せず、他のプロセスから簡単にアクセスできません(前述のように、sans、デバッガーを起動してアタッチします)。関連するシェルプロセス自体内で実行される組み込みdisown
コマンドを除いて、これらにアクセスするためのIPCメカニズムまたはコマンドラインツールはありません。(これはwhy組み込みコマンドです。)
これが、同じログインセッション内であっても、2番目のシェルからのdisown
ジョブすらできない理由です。 disown
は、完全にシェルごと、シェルプロセスごとのものです。
別のシェルからプロセスをバックグラウンドで実行することは可能です。
実際、それはあなたがやっていたことではありません。
foregroundおよびbackgroundの概念は、セッション。具体的には、制御端末に知られている1つのプロセスグループ、つまりフォアグラウンドプロセスグループがあります。プロセスを停止して続行しても、それ自体でプロセスをフォアグラウンドとバックグラウンドの間で切り替えることはありません。制御端末のフォアグラウンドプロセスグループも更新する必要があります。 フォアグラウンドプロセスは、そのフォアグラウンドプロセスグループのメンバーであることによって、フォアグラウンドにのみ存在します。そのセッションの他のすべてのプロセスグループ、つまりこれらのプロセスグループのプロセスは、バックグラウンドで実行されます。
皮肉なことに、別のシェルからこれを行っていません。あなたがやっていることは、アクションを実行するために元のシェルプロセスをトリガーしています。フォアグラウンドプロセスグループの停止のメインプロセスを確認し、それに応じて端末のフォアグラウンドプロセスグループを調整します(独自のプロセスグループに戻します)。
ちなみに、正しいシグナルはSIGTSTP
です。
Solarisを使用している場合は、次のように呼び出すことができます。
Nohup -p <pid>
これにより、現在の制御端末が削除され、stdoutがファイルシステム内のファイルに接続されます。
これを行うには、カーネル(この場合は/ procファイルシステム)からのサポートが必要です。 2001年にNohup
プログラムのサポートがSolarisに追加されました。他のプラットフォームが他の端末から実行中のプロセスにデバッガを接続できる場合、この機能を追加できます。
ところで、以前にプロセスを実行していたシェルを見ると、シェルのwait()呼び出しから「子がありません」というエラーメッセージが表示されることがあります。
私は現在、他のプラットフォームで同様の構造を認識していません。