为什么注释掉 trap 函数可以让 control-c 工作?

为什么注释掉 trap 函数可以让 control-c 工作?

在启动 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

进一步阅读:

答案2

在终端中按Ctrl+C会发送 SIGINT信号到终端中运行的进程。 (更准确地说,发送到前台进程组中的所有进程;例如,如果您正在运行foo | tail -f,则信号将发送到 和footail

的常规含义信号情报(中断信号)是“中止当前任务并返回交互式提示”。没有交互式提示的程序(例如 tail)只需退出即可让 shell 接管。

trap命令定义 shell 收到信号时的行为。例如,当trap 'echo killed' INTshellkilled收到 SIGINT 信号时进行打印。trap 'echo killed' 2在 Linux PC 上也是一样,因为 2 是名称为 INT 的信号的编号。仅当 shell 收到信号时才会触发,如果另一个程序位于前台则不会触发。

trap "" INT是一个特例。它不仅告诉 shell 在收到信号时不执行任何操作,还告诉 shell忽略信号。当进程为信号注册处理程序时,这不会影响它运行的程序 - 处理程序是进程中的代码,无法从另一个程序调用它。但是忽略信号是一种不同的设置,当一个程序运行另一个程序时,该设置会被保留。所以之后trap "" INT,当你运行 时tail,信号仍然被忽略,并且按Ctrl+C没有效果。

如果您希望有效地忽略 shell 中的信号,但不忽略其启动的程序中的信号,请设置一个非空陷阱,例如trap " " INTor trap : INT:是 shell 的 no-op 命令)。或者,trap - INT在运行之前运行tail以将信号处理重置为其默认的非忽略状态。

答案3

trap是 shell 内置的,正常格式是trap cmd list_of_signals.cmd在你的情况下是空的,即忽略该信号。1hangup信号,3intrCtrl-C。进一步的解释参见man bash章节。Shell Builtin Commands

相关内容