我试图让脚本在标准输入重定向时要求输入工作。这可能是不可能的,但我想了解为什么。这是一个例子:
$ 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"
因此,上述结果保存在./prompt
、chmod +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 或类似的程序运行。