標準入力がリダイレクトされたときに入力を要求したときに機能するスクリプトを取得しようとしています。不可能かもしれませんが、その理由を知りたいです。例は次のとおりです。
$ 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
おそらく。 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の標準入力に2回リダイレクトするので動作しません。リダイレクト(後で)が< <(echo answer)
適用され、Pythonはその単語をanswer
実行するスクリプトにインポートします。
/dev/tty
オープン(偶数)は、stdinがリダイレクトされている場合でも機能します。/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;'
もちろん、これを行うには、cronやそれと似ていないttyを使ってスクリプトを実行する必要があります。