Shell没有显示输入命令,“重置”工作,但发生了什么?

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

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

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

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

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

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

$ grep foo * -l | xargs vim 

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

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

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

编辑

给予

 stty --all 

命令按照John S. Gruber的要求给出了以下输出(为了便于阅读而编辑了空格)

 speed 0 baud; rows 53; columns 186; line = 0; intr = ; quit = ; erase = ; kill = ; eof = ; eol = ; eol2 = ; swtch = ; start = ; stop = ; susp = ; rprnt = ; werase = ; lnext = ; flush = ; 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调用向内核发出信号,表示他们不希望出现这种情况。 他们也不希望特殊角色做特殊的事情。 相反,他们要求内核提供“原始”模式。 特别是,编辑器像vim关闭各种“回声设置”。 所有这些都适用于计算机串行线路上的真实终端,或Alt + Ctrl + F1的虚拟终端,或者在GUI下运行类似gnome-terminal的虚拟终端。

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

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

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

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

这里有更多的参考资料,另一个有趣的是这里 另一个有趣的解决方案是在https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour的回答中给出的。

我会在系统上启动一个新用户(我的意思是创建一个新的干净用户并在那里登录),看看问题是否存在。 如果不是 – 那么它就是你的终端或你的X11设置。