Hier ist ein Versuch, der versucht, das Beenden eines Prozesses zu vermeiden, nachdem er bereits beendet wurde, wodurch die Wahrscheinlichkeit verringert wird, dass ein anderer Prozess mit derselben Prozess-ID beendet wird (obwohl es wahrscheinlich unmöglich ist, diese Art von Fehler vollständig zu vermeiden).
run_with_timeout ()
{
t=$1
shift
echo "running \"$*\" with timeout $t"
(
# first, run process in background
(exec sh -c "$*") &
pid=$!
echo $pid
# the timeout shell
(sleep $t ; echo timeout) &
waiter=$!
echo $waiter
# finally, allow process to end naturally
wait $pid
echo $?
) \
| (read pid
read waiter
if test $waiter != timeout ; then
read status
else
status=timeout
fi
# if we timed out, kill the process
if test $status = timeout ; then
kill $pid
exit 99
else
# if the program exited normally, kill the waiting shell
kill $waiter
exit $status
fi
)
}
Verwenden Sie like run_with_timeout 3 sleep 10000
, das ausgeführt wird, sleep 10000
aber nach 3 Sekunden beendet wird.
Dies ist wie bei anderen Antworten, bei denen ein Hintergrund-Timeout-Prozess verwendet wird, um den untergeordneten Prozess nach einer Verzögerung abzubrechen. Ich denke, dies entspricht fast der erweiterten Antwort von Dan ( https://stackoverflow.com/a/5161274/1351983 ), außer dass die Timeout-Shell nicht beendet wird, wenn sie bereits beendet ist.
Nach dem Ende dieses Programms werden noch einige "Schlaf" -Prozesse ausgeführt, die jedoch harmlos sein sollten.
Dies ist möglicherweise eine bessere Lösung als meine andere Antwort, da die nicht tragbare Shell-Funktion nicht verwendet wird read -t
und nicht verwendet wird pgrep
.