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


Shell没有显示输入命令,“reset”有效,但是发生了什么?

, ,

问题描述

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

我已经遇到过这个问题很多次了,我不明白是什么原因引起的。我知道如何解决这个问题,但是当我”voodooing”解决问题时,我真的不喜欢它。

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

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

  • 我键入”ls”

  • 我只看到一个空的提示,仅此而已

  • 我按回车键,我给出了一个文件列表,换句话说:执行命令

  • 当我给出”reset”命令时,shell再次开始正常工作

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

$ grep foo * -l | xargs vim

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

我的猜测是,这两个问题都有一个潜在的原因,但我有点难以理解这个原因是什么。

搜索这个问题本身就有问题,因为描述有点模糊,没有硬search-terms。

编辑

给予

stty --all

命令按照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

最佳解决办法

当你在shell中运行shell或大多数程序时,你输入的任何东西都会被内核的tty子系统回送给用户的终端。对于擦除字符,Ctrl + R,Ctrl + Z等,还有其他特殊处理。

从命令行运行的某些程序(特别是编辑器)不需要或不需要这样。出于这个原因,他们通过针对tty(终端)设备的IOCTL调用向内核发出信号,表示他们不希望出现这种情况。他们也不希望特殊角色做特殊的事情。相反,他们要求内核提供”raw”模式。特别是,编辑器像vim关闭各种”echo settings”。所有这些都适用于计算机串行线路上的真实终端,或Alt + Ctrl + F1的虚拟终端,或者在GUI下运行gnome-terminal之类的虚拟终端。

这些程序应该通过输入退出编辑器命令或通过接收信号(来自Control + C)来重置它们在退出之前在虚拟tty上更改的任何模式。

如果他们不能正确地做到这一点,那么tty就会处于你发现的有趣状态。由于程序无法重置终端,因此编写了reset命令以允许用户恢复。

我假设中断正在搞乱你正在运行的python软件。我猜这个程序没有机会重置终端,或者根本没有这样做。

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

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

问题在https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state的其他地方描述。

针对vim案例的解决方案是避免使用xargs并使用:

 vim $(grep foo * -l)

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

更多参考文献here,以及另一个有趣的here。另一个有趣的解决方案是在回答https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour时给出的。

参考资料

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