Wie kann man dafür sorgen, dass sich timeout(1) in cron so verhält wie in einer interaktiven Shell?

Wie kann man dafür sorgen, dass sich timeout(1) in cron so verhält wie in einer interaktiven Shell?

Ausführen dieses Befehls in einer interaktiven Bash:

$ timeout 1 sleep 2; echo $?
124

kehrt zurück124nach 1 Sekunde, wie erwartet und wie in timeout(1) dokumentiert.

Wenn ich das Gleiche jedoch als Cron-Job ausführe oder als Befehlszeichenfolge an Bash weitergebe, geschieht Folgendes nicht:

$ bash -c "timeout 1 sleep 2; echo $?"
0

Das Hinzufügen -izum Bash-Aufruf hilft nicht, ebenso wenig wie die Verwendung des --foregroundParameters für timeout(1). Ich habe dasselbe auch mit ksh und zsh versucht, aber immer das gleiche Ergebnis erhalten, also nehme ich an, dass es etwas mit der Funktionsweise von timeout(1) zu tun haben muss.

Ich habe ein bisschen im Internet gesucht und herausgefunden, dass es damit zu tun haben könnte, wie die Signalisierung durch die Prozessgruppen verläuft, aber ich konnte keine Lösung finden, wie man das Timeout im nicht-interaktiven Fall wie erwartet zum Laufen bringt.

Irgendwelche Hinweise, wie ich das erreichen könnte? Letztendlich möchte ich einen Befehl in Cron ausführen, der wahrscheinlich für immer blockiert, und ich möchte diesen Fall zuverlässig erkennen.

Antwort1

Aufgrund der Anführungszeichen $?wird erweitertVorder Bash-Befehl aufgerufen wird. Er wird ersetzt durch den Exit-Status desvorherigeBefehl (der der erste war exit $?)

Eine kurze Demo

bash -c 'exit 42'
bash -c "timeout 1 sleep 2; echo $?"   # => 42

Die Lösung besteht in der VerwendungEinzelzitatedamit der aktuelle interaktive Bash-Prozess die Variable nicht erweitert

bash -c 'timeout 1 sleep 2; echo $?'   # => 124

Antwort2

Sie können versuchen, den Befehl wie folgt auszuführen:

bash -c "timeout 1 sleep 2"; echo $?

verwandte Informationen