當我sleep
手動運行然後kill -INT
它時,睡眠立即退出。例如:
$ /bin/sleep 60 &
[1] 4002356
$ kill -INT 4002356
[1]+ Interrupt /bin/sleep 60
$ ps -C sleep
PID TTY TIME CMD
$
但是,當我在 shell 腳本中執行相同的操作時,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
SIGINT
當我sleep
在 shell 腳本中運行時,為什麼/如何 sleep 會被忽略?
dash
我對和 也有同樣的行為bash
。我的核心是Linux 5.4.0。
答案1
在/bin/sleep 10 &
終止&
中使 shellsleep
異步運行。預設情況下,腳本中會停用作業控制。在 Bash 中,以下內容適用 [強調我的]:
Bash 啟動的非內建指令將訊號處理程序設定為 shell 從其父級繼承的值。當作業控制無效時,非同步指令忽略 SIGINT除了這些繼承的處理程序之外,還有 SIGQUIT。
來源:Bash 參考手冊。
相關地,SIG_IGN
在對 的呼叫中持續存在execv()
,但可能存在例外SIGCHLD
。
在呼叫過程映像中設定為預設操作 (SIG_DFL) 的訊號應在新過程映像中設定為預設操作。除 SIGCHLD 外,呼叫過程映像設定為忽略的訊號 (SIG_IGN) 應設定為由新過程映像忽略。設定為由呼叫過程映像擷取的訊號應設定為新過程映像中的預設操作(請參閱<signal.h>)。