Abrufen der PID des Befehls früher in der Pipeline

11

Ich schreibe ein Bash-Skript, mit inotifywaitdem ich ein Verzeichnis überwachen und Aktionen starten kann, wenn Änderungen erkannt werden. Etwas wie:

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

Da inotifywaitdieses Skript nicht von selbst beendet wird, wird es nicht angehalten.

Mein Plan war es also, die PID des inotifywait-Prozesses zu erhalten, sie in einer Datei zu speichern und sie später von einem anderen Prozess beenden zu lassen.

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

Aber ich weiß nicht, wie ich die PID bekommen soll. Gibt es einen einfachen Weg, dies zu erreichen? Eine andere Möglichkeit besteht darin, die PID des Shell-Skripts $$in der Datei zu speichern und das gesamte Shell-Skript zu beenden, aber ich wollte nach der while-Schleife eine Bereinigung durchführen.

Ich habe versucht, es zu verwenden, coprocund ich denke, es wird funktionieren, aber es scheint komplizierter als nötig zu sein.

Adrian Pronk
quelle
Sie könnten so etwas wie `ps -ef | verwenden grep processName | grep -v grep | awk '{print $ 2}' | Xargs töten -9 `
Kiwy
@ Kiwy - stattdessen mache ich einfach ein pgrep inotifywait. Das gibt dir die PID, um zu töten , pkill inotifwait.
slm
@slm Abhängig von Ihrem System haben Sie nicht pgrep und pkill, während grep und ps fast vorhanden sind. Sie sind willkommen
Kiwy
@ Kiwy - zweifelhaft, diese Tools sind ziemlich allgegenwärtig. Auch müssen Sie nicht a tun grep -v grep, sondern ps -ef | grep [p]rocessname...würden das gleiche tun.
slm
1
@DavidsonChua - Ja, Sie können den -fSchalter verwenden, wenn Sie mit mehr Namen der ausführbaren Dateien übereinstimmen müssen.
slm

Antworten:

6

In einer Pipeline werden alle Prozesse gleichzeitig gestartet . Es gibt keinen, der früher als die anderen ist.

Du könntest es tun:

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

Oder tragbar:

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

Beachten Sie auch, dass die Subshell, die die whileSchleife ausführt, inotifywaitbeim nächsten Schreiben automatisch beendet wird, wenn sie etwas in stdout schreibt.

Stéphane Chazelas
quelle
3

Wenn Sie die Prozess-ID in der Schleife benötigen, drucken Sie sie zuerst aus.

sh -c 'echo "$$"; exec inotifywait -m ...' | {
  read inotifywait_pid
  while IFS= read -r f; do
    
    if …; then kill "$inotifywait_pid"; break;
  done
}
Gilles 'SO - hör auf böse zu sein'
quelle
1

Diese SO-Antwort scheint zutreffend:

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