CTRL + 4(和CTRL + \)在bash中做什么?


22

我只是偶然发现CTRL+ 4 关闭stdin了从命令行读取输入的程序。

当我 在程序阅读中键入CTRL+ 4CTRL+ 时,它是这样的/stdin

$ cat
wefwef
wefwef
^\Quit
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
^\Quit
$

我得到^\Quit显示,然后程序关闭。与使用^C或相比有什么区别^D?怎么^\Quit办?

编辑:发现CTRL+ \做同样的事情。

Answers:


37

Ctrl + 4发送^ \

终端发送字符(或更准确地说是字节),而不是键。当按下代表可打印字符的键时,终端会将该字符发送到应用程序。大多数功能键都编码为转义序列:以字符号27开头的字符序列。Ctrl+ 形式的某些character键和一些功能键作为控制字符发送-在ASCII字符集中,这是所有现代计算机都使用的使用为基础(Unicode的,ISO拉丁语ñ等等都是ASCII的超集),33个字符是控制字符:字符数字0到31和127。控制字符不可打印,但打算在应用程序中起作用。例如,字符10(它是Control-J(通常写为^ J))是换行符,因此当终端显示该字符时,它将光标移动到下一行,而不是显示字形。转义字符本身是控制字符^ [(值27)。

没有足够的控制字符来覆盖所有Ctrl+ character琴弦。只有字母和字符@[\]^_?具有相应的控制字符。当您按Ctrl+ 4Ctrl+ $(我想是Ctrl+ Shift+ 4)时,终端必须选择要发送的内容。根据终端及其配置,有几种常见的可能性:

  • 终端会忽略Ctrl修饰符并发送字符4$
  • 终端发送一个转义序列,该序列对按下的确切键和修饰符进行编码。
  • 终端发送其他控制字符。

许多终端发送数字行中某些键的控制字符:

  • Ctrl+ 2→^ @
  • Ctrl+ 3→^ [
  • Ctrl+ 4→^ \
  • Ctrl+ 5→^]
  • Ctrl+ 6→^^
  • Ctrl+ 7→^ _
  • Ctrl+ 8→^?

我不知道这个特殊的约定在哪里出现。

Ctrl+ |发送相同的字符,因为它是Ctrl+ Shift+,\并且无论是否按下Shift键,终端都会发送^ \。

^ \退出

终端本身(更确切地说是内核中的通用终端支持)专门解释一些控制字符。可以将这种解释配置为映射不同的字符,或者由想要自己处理字符的应用程序将其关闭。一种众所周知的解释是,Return键M发送的字符^ M 将当前行发送到应用程序(如果终端处于熟模式),在该模式下,应用程序逐行接收输入。

一些字符将信号发送到前台的应用程序。^ C发送中断信号(SIGINT),该信号通常告诉应用程序停止正在执行的操作并读取用户的下一条命令。非交互式应用程序通常会退出。^ \发送退出信号(SIGQUIT),该信号通常告诉应用程序尽快退出而不保存任何内容;许多应用程序不会覆盖默认行为,即立即终止应用程序¹。所以,当你按下Ctrl+ 4(或任何发送^ \字符)在cat或者bc,两者都不覆盖缺省行为,应用程序被杀害。

终端本身会打印^\消息的一部分:这是对您键入的字符的直观描述,并且终端处于烹饪模式并启用了回显功能(终端会在您键入字符后立即显示字符,而不是非回显模式,其中字符仅发送到应用程序,可能会选择也可能不会选择显示它们。该Quit部分来自bash:它注意到其子进程因退出信号而死亡,这是让您知道的方式。

外壳程序会处理所有常见信号,因此,如果您在外壳程序中键入^ \,则不会终止会话,您只会得到一个新的提示,与^ C相同。

您可以使用该stty命令来播放终端设置。

¹ 传统上会生成核心转储,但如今许多系统默认将其禁用。


SIGINT杀死前台进程组,而SIGQUIT通过核心转储杀死它。两种信号都可以处理。我不确定通过阅读下一条命令意味着什么。系统不会禁用核心转储,除非将初始coredumpsize限制设置为0(不是硬限制,通常您可以随意提高它)。
斯特凡Chazelas

@StéphaneChazelas在执行用户交互的程序中,SIGINT的通常语义是取消当前用户命令并允许用户与该程序进行交互,即返回主命令循环。另一方面,我不记得看到过一个程序,其中SIGQUIT不会退出(除非信号处理程序中有错误)。实际上,许多系统默认情况下禁用核心转储的方法是将核心转储大小软限制设置为0,从而使用户可以随意更改此默认设置。
吉尔(Gilles)'所以

例外。SIGINT终止当前正在运行的任务。只有少数应用程序可以扩展该功能以终止其自己的“前景”任务。您一定在想lessvim。需要注意的是在cmd | lessCTRL-C它通常杀cmd(而less它的处理,以取消目前的动作(如搜索))(续)
斯特凡Chazelas

在这方面,我发现您的回答措词令人困惑。通常不处理SIGQUIT的事实是,没有以相同的方式使用它。您按CTRL-C中止当前正在执行的操作。您只会偶尔使用CTRL- \进行调试以生成核心转储。通常,没有任何理由使应用程序想要以您的方式尝试这样做。
斯特凡Chazelas

@StéphaneChazelas不仅如此,而且vim,大多数基于终端的应用程序都可以读取用户命令。例如REPL(bash,破折号,ksh,zsh,python,irb,fsharpi,Mathematica等)。这并不少见。您的第一个注释对象将SIGINT和SIGQUIT绘制得太不同,而您最新的注释对象将SIGINT和SIGQUIT绘制得太相似,这使我对您要行驶的内容感到困惑。
吉尔(Gilles)'所以别再邪恶了'

7

除了Gilles的答案,我还要补充一点,您始终可以使用Ctrl-v+ key(在本例中为Ctrl-v+ Ctrl+4)在bash中输入不可打印的字符,并使用

$ printf '^\' | od -An -tu    # input ^\ as C-v C-4
28

您将获得字符的十进制代码,您可以将其检入man ascii文件分隔符(FS)


那么ctrl + v会做什么?我已经习惯了“粘贴剪贴板”。
JDługosz

2
@JDługosz:Ctrl-V告诉终端不要解释以下字符。不幸的是,GUI组合键接管了这些控制字符,从而造成不必要的混乱。过去,Linux使用Alt- [Key]作为GUI密钥(例如,Alt-C / Alt / V用于复制/粘贴),但是后来人们显然认为与Windows相同是更重要的。同时Mac用户仍然可以使用Command键而不是Ctrl键进行这些操作。
celtschk 2015年

的(较短)的命令是:printf '%d\n' '"^\'
艾萨克(Isaac)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.