Warten Sie, bis der Prozess mit pid $$ beendet ist

13

Sagen wir, ich habe eine PID in der Hand, mypid=$$

Gibt es einen Bash / System-Befehl, mit dem ich auf das Beenden dieses Prozesses mit der angegebenen PID warten kann?

Wenn kein Prozess mit mypid existiert, sollte der Befehl einfach fehlschlagen.

Alexander Mills
quelle
Ich benutze kein C #, aber anscheinend muss es einen Weg geben: msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx
Alexander Mills
Unter Unix wird häufig auf untergeordnete Prozesse gewartet , die waitin der Shell oder in der wait()C-Bibliotheksfunktion verwendet werden. Es gibt keine Standardmethode für AFAIK, um auf einen nicht untergeordneten Prozess zu warten. Es ist weiterhin unklar, ob die C # -Funktion dies kann (dies hängt davon ab, was ein "assoziierter Prozess" ist).
Kusalananda
Ich könnte dies mit Umfragen tun, aber das wäre schrecklich
Alexander Mills
Es würde möglicherweise auch zu falschen Ergebnissen führen. Die Wiederverwendung von PID kann theoretisch bedeuten, dass ein Prozess mit derselben PID wie der Prozess, auf den Sie warten, zum Leben erweckt wird. Unter Linux (mit sequentiellen PIDs) wäre dies unwahrscheinlich , auf Systemen wie OpenBSD (randomisierte PID-Zuweisung) wäre dies jedoch ein Problem.
Kusalananda

Antworten:

18

Ich habe aus dieser Antwort das bekommen, was ich brauchte: /programming//a/41613532/1223975

..turns out using wait <pid> funktioniert nur, wenn diese PID ein untergeordneter Prozess des aktuellen Prozesses ist .

Folgendes funktioniert jedoch für jeden Prozess:

Warten, bis ein Vorgang abgeschlossen ist

Linux:

tail --pid=$pid -f /dev/null

Darwin (erfordert, dass $pidoffene Dateien hat):

lsof -p $pid +r 1 &>/dev/null

Mit Zeitüberschreitung (Sekunden)

Linux:

timeout $timeout tail --pid=$pid -f /dev/null

Darwin (erfordert, dass $pidoffene Dateien hat):

lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
Alexander Mills
quelle
Es ist nicht mit Linux verwandt, es ist eine Funktion von GNU Tail. Es funktioniert also auf jedem System mit GNU-Tail wie GNU / Linux und nicht auf Nicht-GNU-Linux-basierten Systemen.
Stéphane Chazelas
Ich befürchte, dass tail / lsof in diesem Fall Polling verwenden wird, zumindest angesichts der empirischen Beweise, die unter MacOS so erscheinen.
Alexander Mills
lsof + r versetzt es in den Wiederholungsmodus, so dass der Befehl jede Sekunde wiederholt wird, so dass es Polling verwendet, verdammt
Alexander Mills
3

Sie können die eingebaute Bash verwenden wait:

$ sleep 10 &
[2] 28751
$ wait 28751
[2]-  Done                    sleep 10
$ help wait
wait: wait [-n] [id ...]
    Wait for job completion and return exit status.

    Waits for each process identified by an ID, which may be a process ID or a
    job specification, and reports its termination status.  If ID is not
    given, waits for all currently active child processes, and the return
    status is zero.  If ID is a a job specification, waits for all processes
    in that job's pipeline.

    If the -n option is supplied, waits for the next job to terminate and
    returns its exit status.

    Exit Status:
    Returns the status of the last ID; fails if ID is invalid or an invalid
    option is given.

Es verwendet den Systemaufruf waitpid()..

$ whatis waitpid
waitpid (2)          - wait for process to change state
Derek Callaway
quelle
schön, dass das bei mir funktioniert, hoffentlich kein Polling unter der Haube, danke!
Alexander Mills
1
Ja, funktioniert nicht für meinen Anwendungsfall, ich erhalte folgende Fehlermeldung: bash: wait: pid 47760 is not a child of this shell... zurück zum Zeichenbrett lol
Alexander Mills
Ich habe eine Antwort, ich habe es gerade gepostet
Alexander Mills
1
Dies wartet nur auf untergeordnete Prozesse, nicht auf einen Prozess, der nicht mit dem aktuellen Prozess verknüpft ist.
Kusalananda