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.


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.


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
}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.