Memperoleh PID dari perintah sebelumnya di Pipeline

11

Saya sedang menulis skrip bash untuk digunakan inotifywaituntuk memantau direktori dan memulai tindakan ketika perubahan terdeteksi. Sesuatu seperti:

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

Karena inotifywaittidak berhenti dengan sendirinya, skrip ini tidak akan berhenti.

Jadi rencana saya adalah untuk mendapatkan PID dari proses inotifywait, menyimpannya ke file dan memiliki proses lain untuk membunuhnya nanti, katakan seperti:

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

Tapi saya tidak tahu bagaimana cara mendapatkan PID. Apakah ada cara sederhana untuk mencapai ini? Cara lain adalah dengan menyimpan PID dari script-shell $$ke file dan membunuh seluruh script-shell tapi saya ingin melakukan pembersihan setelah loop sementara.

Saya sudah mencoba menggunakan coprocdan saya pikir ini akan berhasil tetapi sepertinya lebih rumit daripada yang diperlukan.

Adrian Pronk
sumber
Anda dapat menggunakan sesuatu seperti ini `id-id | grep processName | grep -v grep | awk '{print $ 2}' | xargs kill -9 `
Kiwy
@ Kiwy - bukannya kekacauan itu lakukan saja pgrep inotifywait. Itu akan memberi Anda PID, untuk membunuh pkill inotifwait,.
slm
@ slm tergantung dari sistem Anda, Anda tidak akan memiliki pgrep dan pkill saat grep dan ps sementara hampir hadir. Anda sedang menyambut
Kiwy
@ Kyiwy - diragukan, alat-alat itu cukup ada di mana-mana. Anda juga tidak perlu melakukan grep -v grep, sebaliknya ps -ef | grep [p]rocessname...akan melakukan hal yang sama.
slm
1
@ Davidvidson - ya Anda dapat menggunakan -fsaklar jika Anda perlu mencocokkan dengan lebih dari nama yang dapat dieksekusi.
slm

Jawaban:

6

Dalam pipa, semua proses dimulai secara bersamaan , tidak ada yang lebih awal dari yang lain.

Anda bisa melakukannya:

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

Atau mudah dibawa:

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

Juga perhatikan bahwa ketika subkulit yang menjalankan whileloop berakhir, inotifywaitakan dibunuh secara otomatis saat berikutnya ia menulis sesuatu ke stdout.

Stéphane Chazelas
sumber
3

Jika Anda memerlukan ID proses dalam loop, cetak terlebih dahulu.

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

Jawaban SO ini tampaknya berlaku:

inotifywait -m file > >(while read f; do echo f; done) &
Aryeh Leib Taurog
sumber