我正在尝试将进程日志捕获到文件中,同时进程接收 SIGINT 信号进行调试。
timeout -s INT 2 ./myprogram 2>&1 | tee /tmp/1
我发现,当我向管道左侧的进程发送SIGINT时,右侧进程也收到SIGINT,这使得
tee
退出并且日志丢失。这让我感到惊讶。我制作了以下脚本来重现它:
$ timeout -s INT 1 bash -xc 'trap "echo LEFT SIGINT >&2; sleep 1" INT; sleep infinity' | bash -xc 'trap "echo RIGHT SIGINT" INT; sleep infinity'
+ trap 'echo RIGHT SIGINT' INT
+ sleep infinity
+ trap 'echo LEFT SIGINT >&2; sleep 1' INT
+ sleep infinity
++ echo LEFT SIGINT
++ echo RIGHT SIGINT
RIGHT SIGINT
LEFT SIGINT
++ sleep 1
脚本在左侧运行
timeout -s INT 1
,它将在 1 秒后向进程 bash
发送 SIGINT 信号,该进程注册 INT
陷阱处理程序并无限休眠,等待被杀死。右侧也运行 bash,并在 INT
上设置陷阱并无限休眠。我的shell是Bash5.2.26.
两个进程都收到了 SIGINT,但仅向左侧进程发送了信号。
为什么正确的进程会收到SIGINT?
这似乎是
timeout
的行为。当我strace
运行它(GNU coreutils 8.30版本)时,我观察到除了向它正在监视的子进程发出信号之外,它还向它自己的整个进程组发送相同的信号。
我还看到它不仅发送请求的信号,还发送
SIGCONT
,我认为这是为了确保接收者在停止时收到主要信号。
我看不出有任何方法可以阻止
timeout
这样做,因此,如果它给您带来麻烦,那么您需要解决它或避免 timeout
。