我已经编写了许多 bash/bind 工具来简化我的命令行存在,并且最近想让其中一个工具具有交互性。如果我尝试在这些脚本之一中从标准输入读取,执行会在读取时锁定。我的示例是在 python 中,但是当调用的脚本是用 ruby 编写时,我看到了完全相同的行为:
~> cat tmp.py
import sys
sys.stdout.write(">>>")
sys.stdout.flush()
foo = sys.stdin.readline()
print "foo: %s" % foo,
~> python tmp.py
>>>yodeling yoda
foo: yodeling yoda
所以脚本有效。当我调用它时,我可以给它输入并打印我输入的内容。
~> bind -x '"\eh":"echo yodeling yoda"'
[output deleted]
~> [Alt-H]
yodeling yoda
bind
按预期工作。绑定的击键调用命令。我一直在使用这些东西,但直到现在,我只调用了不需要读取标准输入的脚本。
让我们将 [Alt-H] 绑定到脚本:
~> bind -x '"\eh":"python tmp.py"'
[output deleted]
现在我们配置为让脚本在被绑定击键调用时从标准输入读取。点击 [Alt-H] 启动脚本,但没有回显任何键入的内容。即使按下 [Crl-D] 也不会结束它。退出的唯一方法是点击 [Crl-C],杀死 readline 中的进程。(sys.stdin.read() 遭受同样的命运。)
~> [Alt-H]
>>>Traceback (most recent call last):
File "tmp.py", line 7, in <module>
foo = sys.stdin.readline()
KeyboardInterrupt
正如我在顶部提到的,我看到了与 ruby 相同的问题,所以我知道这与我使用的语言无关。(我省略了脚本。)
~> bind -x '"\eh":"ruby tmp.rb"'
[Output deleted]
~> [Alt-H]
>>>tmp.rb:3:in `gets': Interrupt
from tmp.rb:3
我已经查看了 Bash 参考手册关于 bind 的条目,它没有说明输入限制。有什么想法吗?
编辑:
如果我在进程卡住时 cat /proc/[PID]/fd/0 ,我会看到正在显示脚本的输入。(奇怪的是,相当数量的字符 - 似乎是随机的 - 没有出现在这里。这个症状只有在我输入了几百字节后才会出现。)
找到了这个,描述了终端如何以及何时在熟模式和生模式之间切换。呼叫stty cooked
和stty echo
在提示开始时,然后stty sane
或stty raw
之后触发一系列新的问题;主要与如何处理绑定字符有关,但只要说它破坏了大多数 alt 绑定(以及更多)就足够了,直到 return 被击中几次。