在启动 rhel VM 后,我正在跟踪一个日志文件(tail -f xyz.log),但是我意识到 control-c 无法退出它。我尝试了 control-z ,但它留下了后台作业,因此我必须手动终止该进程(tail -f xyz.log)。
我店里有人告诉我在 /etc/profile 中注释掉 trap 函数,我就这样做了。
#trap "" 1 2 3 15
然后注销并重新登录到shell环境,control-c开始工作!
我只是想了解发生了什么事。我做了“男人陷阱”,但不幸的是我没有很好地消耗其中的内容。感谢您花时间阅读本文。
答案1
给定的trap
命令告诉 shell 拦截这些信号:
1 SIGHUP
2 SIGINT
3 SIGQUIT
15SIGTERM
“”是收到这些信号之一时要运行的命令。换句话说,什么也不做;完全忽略这些信号。
您可以使用 来查看哪些字符绑定到信号stty -a
,例如,在此示例中输出的第二行stty
(格式取决于您使用的系统):
$ stty -a
speed 38400 baud; rows 40; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
一些字符和信号之间的对应关系如下11.1.9 特殊字符,例如,
intr
发送SIGINT
quit
发送SIGQUIT
所以我^C
会发送SIGINT
(您的配置可能有所不同)。
一旦您注释掉trap
,shell 就会恢复到其默认行为,这使得这些特殊字符在您键入时发送信号,例如,^\
发送SIGQUIT
并^C
发送SIGINT
。
进一步阅读:
- trap - 陷阱信号(POSIX shell 内置),其中注释
如果行动为 null ( "" ),shell 将忽略每个指定的条件(如果出现)。
- Kill - 终止或向进程发出信号(也是 POSIX,显示标准信号名称及其数值)。
- stty - 设置终端选项
- SIGINT 与其他终止信号有何关系?
答案2
在终端中按Ctrl+C会发送 SIGINT信号到终端中运行的进程。 (更准确地说,发送到前台进程组中的所有进程;例如,如果您正在运行foo | tail -f
,则信号将发送到 和foo
。tail
)
的常规含义信号情报(中断信号)是“中止当前任务并返回交互式提示”。没有交互式提示的程序(例如 tail)只需退出即可让 shell 接管。
这trap
命令定义 shell 收到信号时的行为。例如,当trap 'echo killed' INT
shellkilled
收到 SIGINT 信号时进行打印。trap 'echo killed' 2
在 Linux PC 上也是一样,因为 2 是名称为 INT 的信号的编号。仅当 shell 收到信号时才会触发,如果另一个程序位于前台则不会触发。
trap "" INT
是一个特例。它不仅告诉 shell 在收到信号时不执行任何操作,还告诉 shell忽略信号。当进程为信号注册处理程序时,这不会影响它运行的程序 - 处理程序是进程中的代码,无法从另一个程序调用它。但是忽略信号是一种不同的设置,当一个程序运行另一个程序时,该设置会被保留。所以之后trap "" INT
,当你运行 时tail
,信号仍然被忽略,并且按Ctrl+C没有效果。
如果您希望有效地忽略 shell 中的信号,但不忽略其启动的程序中的信号,请设置一个非空陷阱,例如trap " " INT
or trap : INT
(:
是 shell 的 no-op 命令)。或者,trap - INT
在运行之前运行tail
以将信号处理重置为其默认的非忽略状态。
答案3
trap
是 shell 内置的,正常格式是trap cmd list_of_signals
.cmd
在你的情况下是空的,即忽略该信号。1
是hangup
信号,3
是intr
或Ctrl-C
。进一步的解释参见man bash
章节。Shell Builtin Commands