Когда я запускаю sleep
вручную, а затем kill -INT
он, sleep немедленно выходит. Например:
$ /bin/sleep 60 &
[1] 4002356
$ kill -INT 4002356
[1]+ Interrupt /bin/sleep 60
$ ps -C sleep
PID TTY TIME CMD
$
Однако, когда я делаю то же самое в скрипте оболочки, sleep
игнорируется SIGINT
. Например:
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
Почему/как sleep игнорирует SIGINT
запуск sleep
внутри скрипта оболочки?
У меня такое же поведение с dash
и bash
. Мое ядро — Linux 5.4.0.
решение1
В /bin/sleep 10 &
терминации &
делает оболочку работающей sleep
асинхронно. Управление заданиями по умолчанию отключено в скрипте. В Bash применяется следующее [выделено мной]:
Невстроенные команды, запускаемые Bash, имеют обработчики сигналов, установленные на значения, унаследованные оболочкой от ее родителя.Когда управление заданиями не действует, асинхронные команды игнорируют SIGINTи SIGQUIT в дополнение к этим унаследованным обработчикам.
Источник:Справочное руководство по Bash.
И, соответственно, SIG_IGN
сохраняется при вызове execv()
, за возможным исключением SIGCHLD
.
Сигналы, установленные на действие по умолчанию (SIG_DFL) в образе вызывающего процесса, должны быть установлены на действие по умолчанию в новом образе процесса. За исключением SIGCHLD, сигналы, установленные на игнорирование (SIG_IGN) образом вызывающего процесса, должны быть установлены на игнорирование новым образом процесса. Сигналы, установленные на перехват образом вызывающего процесса, должны быть установлены на действие по умолчанию в новом образе процесса (см. <signal.h>).
Источник:Технические характеристики Open Group Base, выпуск 7, издание 2018 г..