web-dev-qa-db-ja.com

別のシェルからプロセスを否認する方法

シェルの終了時にプロセスが停止しないようにするには、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を使用しています

2
Golgot

これは不可能です。

まあ、それはデバッガでふざけてシェルプログラムを実行しているプロセスの内部を突く準備ができている場合です。より具体的には、これはシェルプログラミングのレベルでは単純明快な方法では不可能です。

これは、disownが、シェルプログラムが個々のシェルプロセスのメモリ空間に保持する「ジョブ」のリストに影響を与えるためです。

シェル(ジョブコントロールシェル、つまり)は、disownによって忘れるように指示されるか、子プロセスが終了してシェルにwait() edし、「ジョブ」の終了を報告しました。 disownは、子プロセスの状態には影響しません。シェルの動作に影響します。

disownedプロセスを忘れているため…

  • wait()が子の終了について通知したときに、「ジョブ」の完了を認識しなくなりました。
  • exit/logoutに指示されたときにプロセスがまだ実行されているかどうかは問題ではなくなりました。そして
  • …ハングアップシグナル自体を受信したとき(または、一部のシェルプログラムの場合、終了してインタラクティブログインシェルであることを認識しているとき)は、子にハングアップシグナルを送信しなくなります。

シェルはこれらのリストを共有せず、他のプロセスから簡単にアクセスできません(前述のように、sans、デバッガーを起動してアタッチします)。関連するシェルプロセス自体内で実行される組み込みdisownコマンドを除いて、これらにアクセスするためのIPCメカニズムまたはコマンドラインツールはありません。(これはwhy組み込みコマンドです。)

これが、同じログインセッション内であっても、2番目のシェルからのdisownジョブすらできない理由です。 disownは、完全にシェルごと、シェルプロセスごとのものです。

さらに…

別のシェルからプロセスをバックグラウンドで実行することは可能です。

実際、それはあなたがやっていたことではありません。

foregroundおよびbackgroundの概念は、セッション。具体的には、制御端末に知られている1つのプロセスグループ、つまりフォアグラウンドプロセスグループがあります。プロセスを停止して続行しても、それ自体でプロセスをフォアグラウンドとバックグラウンドの間で切り替えることはありません。制御端末のフォアグラウンドプロセスグループも更新する必要がありますフォアグラウンドプロセスは、そのフォアグラウンドプロセスグループのメンバーであることによって、フォアグラウンドにのみ存在します。そのセッションの他のすべてのプロセスグループ、つまりこれらのプロセスグループのプロセスは、バックグラウンドで実行されます。

皮肉なことに、別のシェルからこれを行っていません。あなたがやっていることは、アクションを実行するために元のシェルプロセスをトリガーしています。フォアグラウンドプロセスグループの停止のメインプロセスを確認し、それに応じて端末のフォアグラウンドプロセスグループを調整します(独自のプロセスグループに戻します)。

ちなみに、正しいシグナルはSIGTSTPです。

参考文献

2
JdeBP

Solarisを使用している場合は、次のように呼び出すことができます。

Nohup -p <pid>

これにより、現在の制御端末が削除され、stdoutがファイルシステム内のファイルに接続されます。

これを行うには、カーネル(この場合は/ procファイルシステム)からのサポートが必要です。 2001年にNohupプログラムのサポートがSolarisに追加されました。他のプラットフォームが他の端末から実行中のプロセスにデバッガを接続できる場合、この機能を追加できます。

ところで、以前にプロセスを実行していたシェルを見ると、シェルのwait()呼び出しから「子がありません」というエラーメッセージが表示されることがあります。

私は現在、他のプラットフォームで同様の構造を認識していません。

0
schily