我编写了许多bash / bind工具来简化命令行的存在,并且最近想要使这些工具中的一个具有交互性。如果我尝试从其中一个脚本中的stdin读取,则执行会在读取时锁定。我的示例是在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
按预期工作。绑定键击调用该命令。我一直使用这些东西,但直到现在,我只调用了不需要stdin读取的脚本。
让我们将[Alt-H]绑定到脚本:
~> bind -x '"\eh":"python tmp.py"'
[output deleted]
现在我们配置为在绑定键击调用时从stdin读取脚本。按[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参考手册条目,它没有说明对输入的限制。有什么想法吗?
编辑:
如果我在进程卡住时cat / proc / [PID] / fd / 0,我会看到脚本的输入正在显示。 (奇怪的是,相当数量的字符 - 似乎是随机的 - 未能出现在这里。只有在我输入几百个字节后才出现这种症状。)
找到this,描述终端如何以及何时在熟和原始模式之间切换。在提示开始时调用stty cooked
和stty echo
,然后stty sane
或stty raw
会触发新的级联问题;主要与如何处理绑定字符有关,但足以说它会破坏大多数alt绑定(以及更多)直到返回被击中几次。
答案 0 :(得分:1)
最后,最好的答案证明是烹饪tty并手动打开echo,然后将tty设置恢复到我开始时的状态:
def _get_terminal_settings():
proc = subprocess.Popen(['/bin/stty', '-g'], stdout=subprocess.PIPE)
settings = proc.communicate()[0]
os.system('stty cooked echo')
return settings
def _set_terminal_settings(settings):
os.system('stty %s' % settings)
...
...
settings = _get_terminal_settings()
user_input = sys.stdin.readline()
_set_terminal_settings(settings)
...
...
您应该能够以您选择的任何语言进行此操作。
如果您对为什么需要这种疯狂感到好奇,我建议您阅读我在上面添加的链接(在EDIT下)。文章没有涵盖任何足够的细节,但你至少比我开始时的理解更多。
答案 1 :(得分:0)
嗯,我的猜测是发生的事情是python脚本正在运行并在按下[Alt-H]时等待stdin的输入,但它的stdin范围与调用脚本的stdin范围不同。当你输入某些内容时,它会转到Bash脚本stdin,而不是pythons。也许找一种方法来“反向管道”或将stdin从bash shell转发到被调用脚本的stdin?
编辑:
好的,我研究了一下,看起来管道可能会起作用。这是一个非常丰富的链接: bash - redirect specific output from 2nd script back to stdin of 1st program?