入力が必要なスクリプトの 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

おそらく。 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を使ってスクリプトを実行する必要があります。

関連情報