问题描述
我的问题是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,你可能会看到同样的问题。
针对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时给出的。