当我们打开终端时,它正在运行。
luvpreet@DHARI-Inspiron-3542:/$
我刚刚打开了它。那么,当我按Ctrl+时C,为什么它不会自行终止并关闭终端?
答案1
Ctrl+C是中断信号。当您在终端中输入此命令时,bash 会向前台的作业发送 SIGINT。如果没有作业(当您刚打开终端时就是这种情况),则不会发生任何事情。终端仿真程序不是在 shell 中运行的作业,因此它不会收到信号并且不会关闭。
如果您想用控制键关闭终端,请使用Ctrl+ D(EOF),这将导致 bash 退出(并且也关闭终端)。
也可以看看:Bash 信号初学者指南并更深入地信号处理的工作原理
注意:自评论发布以来,此答案已被编辑。
答案2
与其他击键*一样,击键^C并不是魔术——它会将键码发送给具有焦点的任何程序。(在 X 中,的键码为 54,修饰符C为 0x4 Ctrl。)接收键流的程序负责对它们进行适当的处理——请记住,在许多 GUI 应用程序中,击键会复制到剪贴板。
当 GUI 终端仿真器(例如 Konsole)或虚拟终端接收到被解释为 的按键时^C,它可以做三件事之一。如果终端处于原始模式,则正在运行的程序要求终端不要执行任何处理特殊键本身并将它们直接传递给程序。一些支持高级功能(如行编辑)的程序在完整的原始击键和处理的文本行之间以某种配置接收键盘输入;bash
例如,一次接收一个击键。^C由终端解释,但退格键按原样发送到 shell。
然而,大多数程序使用熟食模式(因为它不是原始的),终端在实际将一些基本按键发送给程序之前会对其进行解释(这就是为什么您可以在 中使用退格键cat
)。在此模式下,终端本身将^C按键转换为SIGINT
信号并将其发送给子进程。由于终端生成了信号,因此它不会感到困惑并终止。
- SysRq真的很神奇。
答案3
^C通常被映射(参见stty -a
)到SIGINT
信号(参见man 7 signal
)。
未被捕获的事件SIGINT
会中断正在运行的进程,但是......
SIGINT
是进程可以指定行为的信号之一(“捕获信号”)。
所谓的“终端”捕获了SIGINT
,然后重新开始工作。
答案4
每个信号都有一个与之关联的默认操作。信号的默认操作是脚本或程序在收到信号时执行的操作。
Ctrl+C发送“中断”信号(信号情报),默认终止正在前台运行的作业的进程。
Ctrl+D告诉终端应该注册一个末梢血在标准输入上,bash 将其解释为希望出口。
进程可以选择忽略 INT 信号,Bash 在交互模式下运行时会这样做。
来自手动的:
当 bash 处于交互状态时,如果没有任何陷阱,它会忽略 SIGTERM(因此 kill 0 不会终止交互 shell),并且会捕获和处理 SIGINT(因此 wait 内置命令是可中断的)。在所有情况下,bash 都会忽略 SIGQUIT。如果作业控制有效,bash 会忽略 SIGTTIN、SIGTTOU 和 SIGTSTP。
理解陷阱:
陷阱是 shell 中响应硬件信号和其他事件的内置函数。它定义并激活当 shell 收到信号或其他特殊条件时要运行的处理程序。
trap [-lp] [arg] [sigspec …]
-l
打印信号名称及其对应编号的列表。-p
显示与每个 SIGNAL_SPEC 相关的陷阱命令。当 shell 收到信号 sigspec 时,将读取并执行 arg。每个 sigspec 都是信号名称或信号编号。信号名称不区分大小写,SIG 前缀是可选的。
如果一个信号规格是0或者出口, arg 在 shell 退出时执行。要理解它,请关闭终端并在编辑.bashrc
文件中的以下行后打开它。
trap 'notify-send "Ctrl D pressed"' 0
Ctrl D 类似于exit
退出终端的命令。
如果您希望 Bash 在收到 INT 信号时退出,即使在交互模式下,您也可以将以下内容添加到~/.bashrc
:
trap 'exit' INT
或者
trap 'exit' 2