3 Stimmen

Wie kann die Ausführung des Hintergrundprozesses in diesem Szenario fortgesetzt werden?

Ich habe 3 Prozesse a.sh, b.sh, c.sh, die im Hintergrund ausgeführt werden.

./a.sh &
pid_a=$!

./b.sh &
pid_b=$!

./c.sh &
pid_c=$!

Ich muss sicherstellen, dass alle drei Prozesse laufen, bis der längste Prozess beendet ist. Wenn c.sh 10 Sekunden, a.sh 3 Sekunden und b.sh 5 Sekunden für die einzelnen Ausführungszeiten benötigt, muss ich a.sh und b.sh erneut ausführen, um sicherzustellen, dass sie bis zur Beendigung von c.sh existieren.

Ich habe diesen Ansatz ausprobiert, der in dem obigen Szenario sicherlich nicht funktioniert

 ./a.sh &
 while ps -p $! > /dev/null; do

./b.sh &
 pid_b=$!

./c.sh &
pid_c=$!

wait $pid_c
done

Wie bekomme ich das?

1voto

chepner Punkte 440093

Sie können temporäre Dateien als Flaggen verwenden, um anzuzeigen, wann die einzelnen Prozesse zum ersten Mal abgeschlossen sind. Führen Sie jedes Skript in einer Hintergrundschleife aus, bis jedes der beiden anderen mindestens einmal abgeschlossen wurde.

flag_dir=$(mktemp -d flagsXXXXX)
flag_a=$flag_dir/a
flag_b=$flag_dir/b
flag_c=$flag_dir/c

( until [[ -f $flag_b && -f $flag_c ]]; do ./a.sh; touch $flag_a; done; ) &
( until [[ -f $flag_a && -f $flag_c ]]; do ./b.sh; touch $flag_b; done; ) &
( until [[ -f $flag_a && -f $flag_b ]]; do ./c.sh; touch $flag_c; done; ) &

# Each until-loop runs until it sees the other two have completed at least one
# cycle. Wait here until each loop finishes.
wait

# Clean up
rm -rf "$flag_dir"

0voto

Samveen Punkte 3452

Erstens: Sie können kill -0 um den Status des Prozesses zu prüfen für c.sh statt mit wait zu warten, bis es beendet ist.

Zweitens können Sie 2 getrennte Prozesse verwenden, um den Status von Skripten zu überwachen a.sh y b.sh

Drittens setzt dies voraus, dass c.sh ist der am längsten laufende Prozess.

Der Überwachungsprozess 1 geht also wie folgt vor:

# I have pid_c
./a.sh &
pid_a=$!
while wait $pid_a; do
    if kill -0 $pid_c; then
        ./a.sh&
        pid_a=$!
    fi
done

und der Monitorprozess 2 macht Folgendes:

# I have pid_c
./b.sh &
pid_b=$!
while wait $pid_b; do
    if kill -0 $pid_c; then
        ./b.sh &
        pid_b=$!
    fi
done

Sie überwachen also die 2 Prozesse getrennt. Wenn Sie sie jedoch auch überwachen müssen, dann starten Sie die Monitore als 2 Hintergrundjobs und eine einfache wait wird warten auf c.sh sowie die 2 Monitore.

注意してください: kill -0 $PID gibt zurück. 0 si $PID läuft oder 1 si $PID ist beendet.

0voto

Henk Langeveld Punkte 7622

[ Note Dies funktioniert nur für Bash. ksh93 kill verhält sich anders].

Solange es mindestens einen Prozess gibt, den Sie beenden können, kill -0 wird Erfolg zurückgeben. Passen Sie das Intervall nach Bedarf an.

#! /bin/bash
interval=1
pids= && for t in 2 3; do
    (sleep $t && echo slept $t seconds) & pids=${pids:+$pids }$!
done

while (kill -0 $pids) 2>& -; do
    sleep $interval
    # optional reporting:
    for pid in $pids; do
        (kill -0 $pid) 2>&- && echo $pid is alive
    done
done

Ergebnisse in:

6463 is alive
6464 is alive
slept 2 seconds
[1]-  Done                    eval sleeper $t
6464 is alive
slept 3 seconds
[2]+  Done                    eval sleeper $t

Eingebaut kill ist in Bezug auf Fehler nicht konsistent:

$ ksh -c 'kill -0 571 6133 && echo ok || echo no'
kill: 571: permission denied
no
$ bash -c 'kill -0 571 6133 && echo ok || echo no'
bash: line 0: kill: (571) - Operation not permitted
ok

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X