要求输入的脚本的 stdin 重定向

要求输入的脚本的 stdin 重定向

我试图让脚本在标准输入重定向时要求输入工作。这可能是不可能的,但我想了解为什么。这是一个例子:

$ echo 'q = raw_input("question ?"); print "\ngot: ", q' | python -  < <(echo answer)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'answer' is not defined

我知道我可以让它工作:

$ python <(echo 'q = raw_input("question ?"); print "\ngot: ", q') < <(echo answer)
question ?
got:  answer

但这是一个过程替代。是否可以仅通过重定向使其工作?

答案1

也许吧。一种方法是打开 TTY 并与之交互:

#!/usr/bin/env expect
package require Tcl 8.5

gets stdin line; puts "stdin: $line"

set tty [open /dev/tty r+]
chan configure $tty -buffering none

puts -nonewline $tty "nimi sina li seme? "
set name [gets $tty]

gets stdin line; puts "stdin: $line"
puts $tty "name: $name"

因此,上述结果保存在./promptchmod +x、 已安装expect等中。

$ (echo foo; echo bar) | ./prompt
stdin: foo
nimi sina li seme? Bob
stdin: bar
name: Bob
$ 

答案2

$ echo 'q = ...' | python -  < <(echo answer)

这是行不通的,因为你两次重定向到 python 的标准输入。 (稍后)的重定向< <(echo answer)生效,并且 python 仅获取该单词answer作为要运行的脚本。

即使 stdin 被重定向,打开/dev/tty(甚至)也可以工作。/dev/stderr

$ echo foo | python -c 'import sys; 
     s = sys.stdin.readline(); 
     print "from stdin:", s; 
     t = open("/dev/tty", "r"); 
     s = t.readline(); 
     print "from tty:", s;'

当然,这要求脚本使用 tty 运行,而不是从 cron 或类似的程序运行。

相关内容