Shell 不显示输入的命令,“重置”有效,但是发生了什么?

Nie*_*Bom 82 command-line bash

我的问题是 Bash shell 停止显示我输入的字符。但是它确实读取了命令。

我遇到过这个问题很多次,我不明白是什么原因造成的。我知道如何解决它,但是当我“巫毒”解决问题时,我真的不喜欢它。

我将描述我遇到这个问题的两种方式:

我正在运行某个进程,http://pythonpaste.org/script/,有时当我停止它或它中断控制时,会返回给 shell。然后当我在 shell 中输入命令时,我输入的字符不会显示出来。当我按回车时,命令提交。例如:

  • 我输入“ls”
  • 我只看到一个空提示,仅此而已
  • 我按回车键,我得到了一个文件列表,换句话说:命令执行
  • 当我给出“重置”命令时,shell 再次开始正常工作

发生这种情况的第二种方式是当我发出这样的命令时:

$ grep foo * -l | xargs vim
Run Code Online (Sandbox Code Playgroud)

我使用 grep 查找具有特定模式的文件,然后我想打开由 grep 生成的所有文件。这就像一个魅力(虽然没有我希望的那么快)。但是当我退出 Vim 时,我的 shell 停止显示我输入的字符。重置命令可解决该问题。

我的猜测是,这两个问题都有一个潜在的原因,但我对这个原因是如何或是什么感到有些困惑。

搜索这个问题本身就是有问题的,因为描述有点模糊,并且没有针对它的硬搜索词。

编辑

给予

stty --all
Run Code Online (Sandbox Code Playgroud)

根据 John S. Gruber 的请求,命令给出了以下输出(为可读性而编辑的空格)

speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>; 
eof = <undef>;
eol = <undef>; 
eol2 = <undef>; 
swtch = <undef>; 
start = <undef>; 
stop = <undef>; 
susp = <undef>;
rprnt = <undef>; 
werase = <undef>; 
lnext = <undef>; 
flush = <undef>; 
min = 0; 
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
Run Code Online (Sandbox Code Playgroud)

Joh*_*ber 90

当在 shell 中运行 shell 或大多数程序时,您键入的任何内容都会被内核的 tty 子系统回显到用户的终端。还有其他特殊处理,用于擦除字符、Ctrl+RCtrl+Z等。

某些从命令行运行的程序(特别是编辑器)不需要或不需要这个。出于这个原因,他们使用IOCTL 调用向 tty(终端)设备发送信号通知内核他们不想要这种行为。他们也不希望特殊角色做特殊的事情。相反,他们要求内核提供“原始”模式。特别是vim之类的编辑器关闭了各种“回声设置”。所有这些都适用于计算机串行线路上的真实 tty 终端,或 处的虚拟终端Alt+Ctrl+F4,或在 GUI 下运行类似 gnome-terminal 之类的程序时获得的真正虚拟终端。

这样的程序应该在退出之前重置他们在他们使用的虚拟 tty 上更改的任何模式,例如通过输入退出编辑器命令或获取信号(来自Ctrl+C)。

如果他们未能正确执行此操作,则 tty 将处于您发现的有趣状态。由于程序可能无法重置终端,reset因此编写了该命令以允许用户恢复。

我假设中断与您正在运行的 python 软件有关。我猜想那个程序没有机会重置终端,或者只是没有这样做。

在 vim 的情况下,当我运行你的例子时,我得到了你描述的相同行为。我还看到一条消息“Vim:警告:输入不是来自终端”(重置时它会消失)。这是因为 vim 不是从 shell 正常启动的。相反,' grep' 和 ' xargs' 命令一直使用标准输入,通常由 tty 占用,用于从greptto传递文件名xargs

在您发布的输出中,stty -a我们可以看到“-echo”,这也证实了这是问题所在。如果您以无法正常处理信号的方式杀死 vim,您可能会看到同样的问题。

该问题在/sf/ask/269683151/ 的其他地方有所描述。

vim 情况的解决方案是避免使用 xargs 并改用:

vim $(grep foo * -l)
Run Code Online (Sandbox Code Playgroud)

这里的文件列表是由 shell 构建的,就像 xargs 一样,但是 shell 正在调用 vim,它直接连接到 tty。有警告消息发送到错误输出文件,vim 正确设置和重置 tty 设置。

另一种reset不清除屏幕的方法是stty sane.

更多的引用在这里,另一个有趣的一个位置。另一个有趣的解决方案在/sf/ask/576018201/的答案中给出。


Gab*_*les 12

TLDR;在终端中运行它,它将不再显示您键入的命令:

reset
Run Code Online (Sandbox Code Playgroud)

您的终端将被清除并重置,您将能够再次看到键入的命令。请注意,在reset上面键入时,您将看不到任何内容,因此在键入之前按Ctrl+以在运行重置命令之前清除任何现有命令或杂散字符可能很有用。Creset

其他人的长回答:Shell 不显示输入的命令,“重置”有效,但是发生了什么?


Mil*_*kus 9

stty sane 让你的终端再次“理智”

重新启用输入字符的回显,包括退格等特殊字符

与 相比reset,它保留了您的终端历史记录/回滚