最後のバックグラウンドアプリケーションのPIDを取得する方法

最後のバックグラウンドアプリケーションのPIDを取得する方法

この質問では:シェルスクリプトで最後に実行されたコマンドのpidを取得する方法は?

スレッドは素晴らしく明確ですが、コマンドがバックグラウンドで実行されるために実際に最後に「&」が必要でない場合はどうなりますか?では、PIDを取得できますか?

ps注:私はandを使用したくありませんgrep。理論的には、プロセスのPIDはコマンドの実行後に見つける必要があるため、この質問をします。

バックグラウンドアプリの例 - これは私が必要としません。独自にバックグラウンドに入るすべてのものに対する一般的な解決策が必要です(誰かが「前景」オプションがまったくないことを強制します)。ただし、ソリューションをテストするには、次の手順を実行します。すばらしく働きます:

私のアプリケーションスクリプト:

#!/bin/bash

(
sleep 10
echo test
sleep 5
) &

ご覧のとおり、「&」はスクリプトの外部ではなく内部にあるため、スクリプトの起動に & は必要ありません。

./my-app ; echo $! | od -c ; jobs | od -c
0000000  \n
0000001
0000000

$! null でjobs何も返しません。 10秒後も「TEST」メッセージが表示され続けます。

ps x | grep my-app | grep -v grep        
14986 pts/5    S      0:00 /bin/bash ./my-app

更新、bash操作がここで機能しないといういくつかの意見が出た後、解決策を探したいと思い、私の希望はbashに限定されません。

ベストアンサー1

到着背景独自に、アプリケーションは子プロセスを分岐し、親プロセスを終了します。シェルはコマンド自体を実行する前に分岐されたプロセスなので、親プロセスについて知っていますが、そのプロセスを作成できる子や孫を見る方法はありません。

これらのバックグラウンドコマンドのより簡単な例は次のとおりです。

$ sh -c 'ps -j; sleep 10 &'
  PID  PGID   SID TTY          TIME CMD
 6562  6562 14469 pts/13   00:00:00 sh
 6563  6562 14469 pts/13   00:00:00 ps
14469 14469 14469 pts/13   00:00:00 zsh

私はプロセスとそのプロセスグループをzsh理解しています。sh

しかし、見えるのは6562のプロセス終了だけです。 6562プロセスが6563プロセスを作成したかどうかを知る方法はありません。

$ ps -j
  PID  PGID   SID TTY          TIME CMD
 6564  6562 14469 pts/13   00:00:00 sleep
 6565  6565 14469 pts/13   00:00:00 ps
14469 14469 14469 pts/13   00:00:00 zsh

ただし、実行中のプロセスも対応する6562プロセスグループにあることがわかりますsleep(ただし、コマンドが新しいプロセスグループまたはセッションを開始するのをやめる方法はありません(通常はデーモンが実行するように)。

これらのプロセスグループは、シェルの相互作用中にのみ作成されます。

あなたができるもう一つのことは次のとおりです。

cmd | cat &
wait

cmdによって生成されたプロセスが標準出力を閉じない限り、catすべてが死ぬまで死ぬことはありません。

おすすめ記事