我可以编写可以很好地捕获的 shell 脚本SIGINT
,但我似乎无法捕获SIGQUIT
.
#!/bin/bash
function die {
echo "Dying on signal $1"
exit 0
}
trap 'die "SIGINT"' SIGINT
trap 'die "SIGQUIT"' SIGQUIT
while true; do
echo "sleeping..."
sleep 5
done
执行此脚本并按下CTRL-C
具有预期的效果,但按下CTRL-\
(据我所知,应该触发)除了在终端中SIGQUIT
打印之外什么都不做。^\
为什么?
我有两个运行理论。首先是 和 的语义SIGINT
不同SIGQUIT
,因此SIGQUIT
只发送到子进程sleep
,而同时SIGINT
发送到子进程和父 bash 进程。如果是这种情况,它记录在哪里?
我的第二个理论是 bash 不仅SIGQUIT
默认忽略(即,有一个无操作处理程序)(如手册页所建议的那样),而且根本不允许它被捕获。这个理论与第一个理论重叠,因为它可能是SIGQUIT
同时发生在父母和孩子身上的情况,但父母 ( bash
) 就是无法捕获它。如果是这种情况,是否有任何方法可以捕获SIGQUIT
bash 脚本?...也许shopt
我可以设置一些?
编辑:这是在运行 bash 4.1.5 的 gnome-terminal 2.32.0 中的 Ubuntu 10.10 上,并且是^\
配置为发出 SIGQUIT(由向其他程序发出 SIGQUIT 报告stty -a
并确认)。^\
ping
更新:我刚刚发现问题一定是由于 gnome-terminal 造成的。如果我从虚拟控制台运行这个脚本(即ctrl-alt-f1
退出 X),当我按下 SIGQUIT 时,它会很好地捕获 SIGQUIT ^\
。相同的 bash 和所有内容,因此唯一的区别必须是终端仿真器。所以现在我的问题变成了:如何配置 gnome-terminal 在这方面表现得像虚拟控制台?我在虚拟控制台和 gnome-terminal 中diff
的输出stty -a
,虽然存在差异,但似乎没有什么直接相关的(例如,它们都有quit = ^\;
)。
更新2:另一个实验。只需$ sleep 60
在 gnome-terminal 中执行;按下^\
,信号未被捕获。现在$ sleep 60
在虚拟控制台中执行;按下^\
并捕获信号 - 进程打印并Quit
退出。但现在$ ping google.com
在 gnome-terminal 中运行并按^\
-- 信号被捕获并按预期处理。所以 gnome-terminal 有一些奇怪的地方,例如 SIGQUIT 可以被某些程序捕获,但不能被其他程序捕获,即使其他程序在从虚拟控制台调用时确实捕获了它。也许我应该升级我的 gnome 终端。