名前付きパイプから標準入力を取得する


10

私がしようとしていることは、ターミナルウィンドウでpythonを実行し、名前付きパイプからstdinにリダイレクトすることです。次に、別のターミナルで名前付きパイプに書き込み、そのコマンドをpythonで実行します。

ターミナル1:

mkfifo p1
python < p1

ターミナル2:

echo -n "print \"Hello World\"" > p1

何が起こるか-pythonが印刷Hello Worldして終了します。私がやりたいことは、次のコマンドを実行するためにpythonを実行し続けることです。シェルでこれを行うにはどうすればよいですか?

回答:


10

必要がある

  • stdinがターミナルではない場合でも、Pythonをインタラクティブに実行します。 python -i
  • パイプの書き込み側を開いたままにしておくと、PythonがEOFを検出して終了します。

そう:

python -i < p1

そして他の場所:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

ありがとう!出来た。私はあなたがしたことをよく知りません。何が起こっているのかを説明するために、回答に詳細を追加していただけませんか。何をしexec 3> p1&3&は何exec 3> &1ですか?ありがとうございました。
ロー卿。

1
あなたの答えはこのバナーを思い出させました-sphotos-b.xx.fbcdn.net/hphotos-ash4/…これはFacebookの友達のカバー写真です:-)
ロード卿。

質問、ここexec 3>&-と同じように機能しexec 3>&1ますか?
ワイルドカード

1
@ワイルドカード私は3>&-ここに書くつもりだったと思う。3>&1同様に機能しますが、ほとんど意味がありません。おかげで
ステファンChazelas

5

書き込みtail -f後にfifoを開いたままにするために使用できますecho

tail -n1 -f p1 | python

なぜこれが機能するのか

pythonはから読んでいp1ます。ファイルの最後に達すると、読み取りを停止します。これは、ファイルが名前付きパイプであっても、ファイルの読み取りの通常の動作です。tail-f、その最後に到達した後(フォロー)フラグをファイルから読み続けます。


echo "print \"Hello World\" " > p1は2番目のターミナルで試しましたが、何も起こりませんでしたが、ターミナルもブロックされませんでした。pythonを備えた端末は、私が^cそれを終了するまでブロックされたままで、pythonによってキーボード割り込みメッセージが表示されてpythonを終了しました。
ロー卿。

tail -f名前付きパイプを介してブロック分割tarアーカイブを解凍するときに、このトリックを使用しました。それは素晴らしく機能しました。
Mael

2

プログラム全体を一度に送信する必要があります。

runを呼び出すとpython < p1、シェルはpythonを呼び出す前に入力を待機します。つまり、Pythonは、データストリーム全体がシェルによって読み取られ、全体がに渡されるまで、実行開始することすらありませんpython

python -u p1代わりに実行しても(つまり、バッファリングされずにファイルから読み取られますp1python、ファイルを実行する前にファイル全体を読み取ろうとします。

この実験を試してください。

ターミナル1:

mkfifo p1
python < p1

ターミナル2:

cat > p1
print "Hello World"
print "Hello World"

複数の行を送信できることがわかりますが、用語1のpythonは何もしません。次にctrl+を押しDます。プログラム全体が一度に実行されます。

つまり、要約すると、Pythonでパイプから読み取る場合は、プログラム全体を送信する必要があります。このように対話的にpythonを使用することはできません。


1

おそらく、テールアプローチの方が優れています(柔軟性が高い)が、代替策として:

{ echo -n "print \"Hello World\""; cat; } > p1

これは期待どおりに機能しません。-n削除された可能性があります。そして、その後、0。echoコマンドを含むターミナルがブロックされます。1。pythonは^cechoターミナルを押して両方のプロセスが終了するまでコマンドを実行しません。
ロー卿。

1
@LordLoh。バッファリングの問題である可能性があります。おそらく、最初の行が最終的にFIFOに書き込まれるように十分な出力が作成されている場合、pythonはコマンドを実行します。しかし、有効な解決策があるので、この問題の解決に力を入れても意味がありません。
Hauke Laging 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.