Pipelineの前半でコマンドのPIDを取得する


11

inotifywaitディレクトリを監視し、変更が検出されたときにアクションを開始するために使用するbashスクリプトを書いています。何かのようなもの:

inotifywait -m ... | while read f; do something; done

inotifywaitはそれ自体で終了しないため、このスクリプトは停止しません。

したがって、私の計画は、inotifywaitプロセスのPIDを取得し、それをファイルに保存して、後で別のプロセスに強制終了させることでした。

inotifywait -m ... | { echo ??PID?? > pid-file; while ... }

しかし、私はPIDを取得する方法がわかりません。これを達成する簡単な方法はありますか?もう1つの方法は、シェルスクリプトのPIDを$$ファイルに保存してシェルスクリプト全体を強制終了することですが、whileループの後にいくつかのクリーンアップを実行したいと思いました。

私は使ってみましcoprocたが、うまくいくと思いますが、必要以上に複雑に思えます。


このようなものを使用できます `ps -ef | grep processName | grep -v grep | awk '{print $ 2}' | xargs kill -9 `
Kiwy

@Kiwy-その混乱の代わりにただpgrep inotifywait。これにより、PIDが得られますpkill inotifwait
slm

@slmはシステムによって異なりますが、grepとpsが存在する間はpgrepとpkillは存在しません。どういたしまして
Kiwy

@Kiwy-疑わしい、これらのツールはかなりユビキタスです。また、を実行する必要はなくgrep -v grep、代わりps -ef | grep [p]rocessname...に同じことを行います。
slm

1
@DavidsonChua-はい-f、実行可能ファイル名の多くと照合する必要がある場合は、スイッチを使用できます。
slm

回答:


6

パイプラインでは、すべてのプロセスが同時に開始されます。他のプロセスより早いプロセスはありません。

あなたがすることができます:

(echo "$BASHPID" > pid-file; exec inotifywait -m ...) | while IFS= read -r...

またはポータブルに:

sh -c 'echo "$$" > pid-file; exec inotifywait -m ...' | while IFS= read -r...

whileループを実行するサブシェルが終了inotifywaitすると、次にstdoutに何かを書き込むときに自動的に強制終了されることにも注意してください。


3

ループ内でプロセスIDが必要な場合は、最初に印刷してください。

sh -c 'echo "$$"; exec inotifywait -m ...' | {
  read inotifywait_pid
  while IFS= read -r f; do
    
    if …; then kill "$inotifywait_pid"; break;
  done
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.