Shell-Script
子 shell 腳本沒有響應發送到前台程序組的終端中斷
我有一個控制一些衛星腳本的主腳本。當我從終端發送中斷信號時,父母
trap
捕捉到信號,但孩子沒有,我不知道為什麼。我沒有更改預設終端設置(我沒有在stty
任何地方執行)。這是我的父子腳本和終端輸出:
家長:
#!/bin/sh ./child.sh & for sig in $(kill -l) ; do trap "echo parent:$sig" $sig done wait
孩子:
#!/bin/sh cat < /dev/tty & PID=$! for sig in $(kill -l) ; do trap "echo child:$sig" $sig done wait
終端互動:
[prompt]$ ./parent.sh ^Cparent:INT cat: stdin: Input/output error [prompt]$
更新
我在 macOS 和 CentOS 上測試了腳本,出現了上述行為。當我使用預設的 Bourne 兼容 shell 在 FreeBSD 上測試它時,孩子收到的信號是
CHLD
.
對於由非互動式 shell 非同步執行的命令(實際上是在未啟用作業控制時),在 POSIX 兼容的
sh
實現中會忽略 SIGINT 和 SIGQUIT。這是一個 POSIX 要求,儘管一些 shell 忽略了它。另一個 POSIX 要求是,如果一個信號在 shell 啟動時被忽略,你不能取消它,所以你搞砸了。
在這裡,您可以使用沒有那些煩人的“功能”(至少在目前版本中)
zsh
來代替。sh
在任何情況下,shell 中的信號處理都是最不可靠和便攜的方面之一。您會發現 shell 之間的行為差異很大,並且通常在同一 shell 的不同版本之間。如果您要嘗試做任何不平凡的事情,請為嚴重的頭髮拉扯和頭部抓撓做好準備。
我建議使用不同的語言,您可以更好地控制發生的事情。
此外,我不會盲目處理所有可能的信號,只會處理您期望接收並知道如何處理的信號。例如,擷取 SIGCHLD (shell 本身對此感興趣,因為它的工作是生成程序並處理它們的終止)可能不會做你想做的事情。