GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash:Warte mit Timeout

Sowohl Ihr Beispiel als auch die akzeptierte Antwort sind zu kompliziert, warum tun Sie das nicht nur Verwenden Sie timeout denn das ist genau sein Anwendungsfall? Die timeout Befehl hat sogar eine eingebaute Option (-k ), um SIGKILL zu senden nach dem Senden des ersten Signals zum Beenden des Befehls (SIGTERM standardmäßig), wenn der Befehl nach dem Senden des Initialsignals noch läuft (siehe man timeout ).

Wenn das Skript nicht unbedingt wait erfordert und den Kontrollfluss nach dem Warten wieder aufnehmen, es ist einfach eine Frage von

timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]

Wenn dies der Fall ist, ist dies jedoch genauso einfach, indem Sie die timeout speichern PIDs stattdessen:

pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]

Z. B.

$ cat t.sh
#!/bin/bash

echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"

.

$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script

Schreiben Sie die PIDs in Dateien und starten Sie die Apps wie folgt:

pidFile=...
( app ; rm $pidFile ; ) &
pid=$!
echo $pid > $pidFile
( sleep 60 ; if [[ -e $pidFile ]]; then killChildrenOf $pid ; fi ; ) &
killerPid=$!

wait $pid
kill $killerPid

Das würde einen weiteren Prozess erzeugen, der für die Zeitüberschreitung schläft und den Prozess beendet, wenn er noch nicht abgeschlossen ist.

Wenn der Prozess schneller abgeschlossen wird, wird die PID-Datei gelöscht und der Killer-Prozess beendet.

killChildrenOf ist ein Skript, das alle Prozesse abruft und alle untergeordneten Elemente einer bestimmten PID beendet. Siehe die Antworten auf diese Frage für verschiedene Möglichkeiten, diese Funktionalität zu implementieren:Bester Weg, um alle untergeordneten Prozesse zu beenden

Wenn Sie BASH verlassen möchten, können Sie PIDs und Timeouts in ein Verzeichnis schreiben und dieses Verzeichnis überwachen. Lesen Sie etwa jede Minute die Einträge und prüfen Sie, welche Prozesse noch vorhanden sind und ob sie abgelaufen sind.

BEARBEITEN Wenn Sie wissen möchten, ob der Prozess erfolgreich beendet wurde, können Sie kill -0 $pid verwenden

BEARBEITEN2 Oder Sie können Prozessgruppen ausprobieren. kevinarpe sagte:Um PGID für eine PID (146322) zu erhalten:

ps -fjww -p 146322 | tail -n 1 | awk '{ print $4 }'

In meinem Fall:145974. Dann kann PGID mit einer speziellen Option von kill verwendet werden, um alle Prozesse in einer Gruppe zu beenden:kill -- -145974


Linux
  1. Bash-Arrays mit Beispielen

  2. Bash-If-Else-Anweisung mit Beispielen

  3. Waitpid entspricht Timeout?

  4. Was macht poll() mit einem Timeout von 0?

  5. Alias ​​mit Variable in Bash

So schreiben Sie ein Bash-Skript mit Beispielen

Bash HereDoc Tutorial mit Beispielen

Bash-Wartebefehl

Wartebefehl in Linux mit Beispielen

So erstellen Sie Dokumente mit Bash-Skripten

Bash If Else Syntax mit Beispielen