当前位置: 首页>>技术问答>>正文


为什么Ctrl-C没有杀死终端本身?

,

问题描述

我们打开它时终端正在运行。

luvpreet@DHARI-Inspiron-3542:/$

我刚打开它。那么,当我按下Ctrl + C时,为什么不自杀并关闭终端?

最佳解决方案

Ctrl + C是中断信号。当您在终端中键入此内容时,bash会将SIGINT发送到前台的作业。如果没有工作(刚刚打开终端时就是这种情况),没有任何反应。终端仿真器程序不是在shell中运行的作业,因此,它不会获得信号而不会关闭。

如果要使用控制键关闭终端,请使用Ctrl + D(EOF),这会导致bash退出(并关闭终端)。

另请参阅:Bash Beginner’s Guide on signals以及更深入的How signal handling works注意:自评论发布以来,此答案已被编辑

次佳解决方案

与其他击键*一样,^C击键并不神奇 – 它会向任何具有焦点的程序发送键码。 (在X中,C的键码为54,Ctrl的修饰符为0x4。)接收密钥流的程序负责执行适当的操作 – 请记住,在许多GUI应用程序中,击键复制到剪贴板。

当GUI终端仿真器(例如,Konsole)或虚拟终端接收到它解释为^C的击键时,它可以执行三件事之一。如果终端处于原始模式,则运行程序要求终端不对自身执行任何特殊键处理并将其直接传递给程序。一些支持行编辑等高级功能的程序在完全原始击键和处理过的文本行之间的某些配置中接收键盘输入;例如,bash一次接收一个键击。 ^C由终端解释,但退格键被发送到shell as-is。

但是,大多数程序都使用熟模式(因为它不是原始模式),终端在实际将它们发送到程序之前解释一些基本的击键(这就是为什么你可以在cat中使用退格键)。在此模式下,终端自身将^C击键转换为SIGINT信号并将其发送到子进程。由于终端产生了信号,因此不会混淆并终止。

  • SysRq真的很神奇。

第三种解决方案

通常将^C定位(参见stty -a)至SIGINT信号(参见man 7 signal)。

un-caught SIGINT中断运行过程,但……

SIGINT是进程可以为(“捕获信号”)指定行为的信号之一。

您所谓的”the terminal”捕获SIGINT,然后重新开始工作。

第四种方案

当我是初学者时,我错过了当我使用命令行的时候我实际上使用了两个单独的程序,一个终端和一个shell(例如bash)

shell是你可能已经知道的,一个程序,它接受输入命令或脚本,执行它们并打印它们的输出。

另一边的终端就像是用户和程序之间的中间人(该程序通常是像bash或fish一样的shell)。终端所做的是例如从键盘读取输入,可能以某种方式处理该输入,并将其重定向到另一个程序(bash)。

另外这也是另一种方式,当另一个程序输出一些东西,某些东西被重定向到终端,然后终端的工作就是将某些东西输出到屏幕上。在获取输入并将其打印到屏幕之间,终端可以以各种方式解释它所获得的输入。

例如,如果程序输出以下顺序:

\e[0;31m some extra foobar text

终端将输出带有红色字母的“一些额外的foobar文本”屏幕。这是因为终端选择以特殊方式处理该奇怪的代码,该代码提示它以红色打印以下输出。

类似地,当用户按下Ctrl - C时,唯一特别之处在于终端选择以特殊方式对待它,此键序列没有任何其他特殊之处。具体来说,这暗示它将中断信号(SIGINT)发送到终端内部运行的进程,即shell。如果此时存在任何由shell生成并且当前正在前台运行的程序,它也会收到信号。现在shell有一个特殊的处理程序用于此信号,没有任何反应。但是大多数程序都有默认的处理程序,在SIGINT的情况下只是退出。

第五种方案

每个信号都有一个与之关联的默认操作。信号的默认操作是脚本或程序在收到信号时执行的操作。

Ctrl + C发送”interrupt”信号(SIGINT),该信号默认为将进程终止到前台运行的作业。

Ctrl + D告诉终端它应该在标准输入上注册一个EOF,bash将其解释为退出的愿望。

进程可以选择忽略INT信号,Bash在交互模式下运行时会这样做。

来自manual

When bash is interactive, in the absence of any traps, it ignores SIGTERM (so that kill 0 does not kill an interactive shell), and SIGINT is caught and handled (so that the wait builtin is interruptible). In all cases, bash ignores SIGQUIT. If job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.


trap理解它:

trap是内置于shell中的功能,可响应硬件信号和其他事件。它定义并激活在shell接收信号或其他特殊条件时运行的处理程序。

trap [-lp] [arg] [sigspec …] 

-l print a list of signal names and their corresponding numbers.
-p display the trap commands associated with each SIGNAL_SPEC.

arg are to be read and executed when the shell receives signal sigspec. Each sigspec is either a signal name or a signal number. Signal names are case insensitive and the SIG prefix is optional.

如果sigspec为0或EXIT,则在shell退出时执行arg。为了理解它,关闭终端&在.bashrc文件中编辑以下行后打开它。

trap 'notify-send "Ctrl D pressed"' 0

Ctrl D类似于exit命令从终端退出。

如果您希望Bash在收到INT信号时退出,即使在交互模式下,您也可以将以下内容添加到~/.bashrc

trap 'exit' INT

要么

trap 'exit' 2

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/2269.html,未经允许,请勿转载。