「ジョブ」は、存在しなくなった実行中のプロセスを示します。

「ジョブ」は、存在しなくなった実行中のプロセスを示します。

バックグラウンドでbashを介して長期実行パイプラインを実行しています。

find / -size +500M -name '*.txt' -mtime +90 |
   xargs -n1 gzip -v9 &

パイプラインの2番目のステップは、大きくて古いファイルが複数あるため、完了するのに時間がかかります。

代わりに、パイプラインの最初の部分がすぐに完了し、パイプラインがいっぱいになることなく完了するため、find正常に終了します。

親プロセスが子プロセスに適しているbashようです。wait

find次のいずれかの方法で実行される(pid 20851)がないため、これを行うことができます。

     ps alx | grep 20851
     pgrep -l find

ゾンビプロセスがなく、20851プロセスIDを持つプロセスがシステムのどこにも見つかりませんでした。

Bashの組み込み機能は、jobsプロセスIDなしでタスクを1行で正しく表示します。

[1]+  Running find / -size +500M -name '*.txt' -mtime +90 | xargs -n1 gzip -v9 &

/bin/jobsOTOH:偶然次のような別々のジョブ制御コマンド()を見つけました。

[1]+ 20851 Running         find / -size +500M -name '*.txt' -mtime +90
     20852 Running         | xargs -n1 gzip -v9 &

そして(間違って)終了した20851検索プロセスを「実行中」とマークします。

これはCentOS(編集:より正確には:Amazon Linux 2 AMI)Linuxにあります。これは/bin/jobs2行のスクリプトであることがわかりました/bin/sh

#!/bin/sh
builtin jobs "$@"

私はこれが私を驚かせた。別のプログラム( )で開始された別のプロセスは、そのプロセスが完了して終了し、ゾンビプロセスではなく、他のプログラムsh()が管理するプロセスの内容をどのように知ることができますか?bash

pid追加:システムの他のメソッド(ps、)が不明なpgrep場合は、終了したプロセス(含む)の詳細をどのように知ることができますか?

編集する:

(1) Billy 叔父さんがコメントで指摘したように、このシステムでは と は/bin/sh同じ/bin/bashですが(/bin/shへのシンボリックリンク/bin/bash/bin/jobsシャバンラインがあるスクリプトなので、別のプロセスで実行されます。

(2)また、ビリーのおじさんのおかげで繁殖が容易になりました。/bin/jobsこれは赤ニシンです。私はそれが出力を生成するものだと誤って考えました。jobs驚くべき出力は、次のように呼び出されたときにbash組み込み関数から来たようです-l

$ sleep 1 | sleep 3600 &
[1] 13616
$ jobs -l
[1]+ 13615 Running                 sleep 1
     13616 Running                 | sleep 3600 &
$ ls /proc/13615
ls: cannot access /proc/13615: No such file or directory

したがって、プロセス13615は存在しませんが、bash組み込みジョブ制御によって「実行中」とマークされますjobs -l

その存在は/bin/jobs私を混乱させ、それが犯人であるに違いないと思って(いいえ)、混乱して疑わしく見えます。私はそれが役に立たないので、システムから削除する必要があると思います(とにかくsh呼び出し元のタスクを表示できない別のプロセスで実行されるスクリプト)。

ベストアンサー1

FWIW、次の方法であなたのケースを再現します。

rhel8$ /bin/jobs(){ jobs -l; }
rhel8$ sleep 1 | sleep 3600 &
[1] 2611
rhel8$ sleep 2
rhel8$ jobs
[1]+  Running                 sleep 1 | sleep 3600 &
rhel8$ /bin/jobs
[1]+  2610 Running                 sleep 1
      2611 Running                 | sleep 3600 &
rhel8$ pgrep 2610
    <nothing!>
rhel8$ ls /proc/2610
ls: cannot access '/proc/2610': No such file or directory
rhel8$ /bin/jobs
[1]+  2610 Running                 sleep 1
      2611 Running                 | sleep 3600 &
rhel8$ cat /bin/jobs
#!/bin/sh
builtin jobs "$@"

または、以下を使用してください(以前よりはるかに悪い)。

rhel8$ unset -f /bin/jobs
rhel8$ export JOBS=$(jobs -l)
rhel8$ builtin(){ echo "$JOBS"; }
rhel8$ export -f builtin
rhel8$ /bin/jobs
[1]+  2610 Running                 sleep 1
      2611 Running                 | sleep 3600 &
rhel8$ type /bin/jobs
/bin/jobs is /bin/jobs

注:すでに説明したように、jobs -lbashは終了したパイププロセスの古い情報を表示し続けますRunning。 IMHO これはバグです。他のシェル(例:zsh、ksh、またはyash)ではこれをDone

おすすめ記事