Wenn ich es sleep
manuell ausführe, kill -INT
wird sleep sofort beendet. Beispiel:
$ /bin/sleep 60 &
[1] 4002356
$ kill -INT 4002356
[1]+ Interrupt /bin/sleep 60
$ ps -C sleep
PID TTY TIME CMD
$
Wenn ich jedoch dasselbe in einem Shell-Skript mache, sleep
wird das ignoriert SIGINT
. Beispiel:
set -o xtrace
echo
/bin/sleep 10 &
child="$!"
/bin/sleep 0.1
ps -C sleep
kill -TERM "$child" # SIGTERM
/bin/sleep 0.1
ps -C sleep
wait "$child" # will return immediately
echo
/bin/sleep 10 &
child="$!"
/bin/sleep 0.1
ps -C sleep
kill -INT "$child" # SIGINT
/bin/sleep 0.1
ps -C sleep
wait "$child" # will wait for 9.8 seconds
Warum/wie wird sleep ignoriert, SIGINT
wenn ich es sleep
innerhalb eines Shell-Skripts ausführe?
Ich erhalte dasselbe Verhalten mit dash
und bash
. Mein Kernel ist Linux 5.4.0.
Antwort1
Beim /bin/sleep 10 &
Beenden &
wird die Shell asynchron ausgeführt sleep
. Die Jobsteuerung ist in einem Skript standardmäßig deaktiviert. In Bash gilt Folgendes [Hervorhebung von mir]:
Bei nicht integrierten Befehlen, die von Bash gestartet werden, sind die Signalhandler auf die Werte eingestellt, die die Shell von ihrem übergeordneten Element geerbt hat.Wenn die Jobsteuerung nicht aktiviert ist, ignorieren asynchrone Befehle SIGINTund SIGQUIT zusätzlich zu diesen geerbten Handlern.
Quelle:Bash-Referenzhandbuch.
Und damit verbunden SIG_IGN
bleibt über einen Aufruf von hinaus bestehen execv()
, mit der möglichen Ausnahme von SIGCHLD
.
Signale, die im aufrufenden Prozessabbild auf die Standardaktion (SIG_DFL) eingestellt sind, müssen im neuen Prozessabbild auf die Standardaktion eingestellt werden. Mit Ausnahme von SIGCHLD müssen Signale, die im aufrufenden Prozessabbild auf Ignorieren (SIG_IGN) eingestellt sind, im neuen Prozessabbild auf Ignorieren eingestellt werden. Signale, die im aufrufenden Prozessabbild auf Abfangen eingestellt sind, müssen im neuen Prozessabbild auf die Standardaktion eingestellt werden (siehe <signal.h>).
Quelle:The Open Group Base Spezifikationen Ausgabe 7, Ausgabe 2018.