3

我可以编写可以很好地捕获的 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) 就是无法捕获它。如果是这种情况,是否有任何方法可以捕获SIGQUITbash 脚本?...也许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 终端。

4

2 回答 2

2

我只能假设这是 gnome-terminal 2.32.0 中的某种错误;我已经升级到 Ubuntu 11.04,使用 gnome-terminal 2.32.1(和 bash 4.2.8)并且 SIGQUIT 现在按预期被困住了。

于 2011-06-19T19:51:51.917 回答
0

我在带有 XFCE 的 Fedora 19 上观察到相同的行为:根据ps s,xfce4-terminal 中的 bash 忽略了 SIGQUIT,正在运行yes >/dev/null &,然后ps s显示即使是子进程也忽略了 SIGQUIT。当我(从同一个终端)运行ssh localhost时,ssh 会话中的 shell 也忽略了 SIGQUIT,但yes >/dev/null &没有。

鉴于上面提到 gnome-terminal 的评论,我猜这个错误是在两个终端的公共部分:vte库。我的是vte-0.28.2-9.fc19.x86_64

于 2013-10-17T07:42:11.490 回答