ささいなPythonスクリプト:
#!/usr/bin/python
import os, sys
sys.stderr.write('I am %s' % os.getpid())
sys.stderr.flush()
print "hello"
sys.stderr.write('I am done')
このスクリプトをBashから実行し、stdoutをFIFOにリダイレクトすると:
$ mkfifo fifo
$ /pyscript > fifo
奇妙なことに、FIFOから読み取る前に:
「私は(PID)です」というメッセージが表示されません。
ps -ef
を使用したスクリプトが表示されません
lsofを使用すると、fifoファイルが開いている人が誰にも表示されません。
FIFOから読み取ると、stderrに書き込んでいる両方のメッセージが同時に表示されます。
何が起こっている?
背景:私はFIFOを作成して 'hello'を書き込むテストを書いています;それからテストを実行し、SUTがnotから読み取られることを期待しますつまり、ファイルを無視するだけです。mkfifo test_fifo; /bin/echo hello > test_fifo &; run_the_test; killall echo
を実行しようとしましたが、驚いたことに、echo
プロセスは存在しません!このようなテストの後で(rm test_fifo
を除いて)どのように「クリーンアップ」する必要がありますか...?
シェルは、ファイルのリダイレクトが正常に完了するまでプログラムを実行しません。コマンド pyscript > fifo
により、シェルがフォークされ、fifo
を開こうとします。これは、一部のプロセスが読み取り用にfifo
を開いた場合にのみ成功します。それまでは、子シェルはパイプ待機状態になります。
$ (sleep 10;ps -l -t pts/0)&
[1] 2574
$ pyscript > fifo
F S UID PID PPID WCHAN TTY CMD
0 S 1000 2554 2535 wait pts/0 bash //interactive Shell
1 S 1000 2574 2554 wait pts/0 bash //fork of Shell, parent of sleep and ps
1 S 1000 2576 2554 pipe_w pts/0 bash //fork of Shell, waiting to open fifo
0 R 1000 2577 2574 - pts/0 ps
パイプまたはFIFOは、両端で同時に開く必要があります。パイプまたはFIFOファイルに書き込むプロセスがない場合) (おそらく、すべてファイルを閉じたか、終了したため)、読み取りはファイルの終わりを返します。パイプへの書き込みまたは読み取りプロセスのないFIFO)は、エラー状態。SIGPIPE信号を生成し、信号が処理またはブロックされるとエラーコードEPIPEで失敗します。
http://www.gnu.org/software/libc/manual/html_node/Pipes-and-FIFOs.html