名前付きパイプに書き込むプログラムを開きたいのですが、誰かが実際に名前付きパイプから読み取るまで書き込みません。これは達成可能ですか?パイプがいつ読み取られるかを知るにはどうすればよいですか?
3 に答える
パイプへの書き込みは、誰かがパイプから読み取るまで実際にブロックされます
$ mkfifo f
$ printf "%s\n" "a" "b" "c" "d" > f & # on bg otherwise it blocks until someone reads it
$ cat < f
a
b
c
d
[1]+ Done printf "%s\n" "a" "b" "c" "d" > f
printf
したがって、上記の例でDoneがいつからパイプが読み取られるかがわかります。
そのため、誰かがパイプから読み取った後にコマンドを実行するのを待つことは、次のように実現できます
printf "%s\n" > f && run_some_command
ただし、コマンドがパイプにデータを送信するだけの場合 (ここでは推測)、データを直接送信できます。データは、誰かがパイプから読み取ったときにのみ送信されるためです。
some_command > f # will block until f is read from
パイプに対して読み取りまたは書き込みを行っているかどうか、および誰がパイプに対して書き込みを行っているかを確認する別の方法は、 ですlsof
。試す
$ lsof f
読み取りまたは書き込みを行っているすべてのプロセスf
が、それらの pid、プロセス名、読み取りまたは書き込みアクションとともにリストされます。man ページを参照してください。
ロックファイルやその他のセマフォ/フラグを実装する以外に、名前付きパイプにリスナーがあるかどうかを判断する方法はないと思います。ただし、別の方向にあるものを検出できる場合があります。 Linus Akesson は、パイプを使用して論理ゲートをシミュレートする方法についてのブログ投稿を書きました。彼のアイデアを実装するために、パイプから実際にデータを取り出すことなく、パイプに待機中のデータがあるかどうかをチェックするツールを作成する必要がありました。
彼のコードを使用して、プラットフォーム用にコンパイルし、データがパイプを介して送信されるのを待っていることを確認した後、パイプからのみ読み取るツールを使用できます。あなたが実際に達成しようとしていることを知らなければ、この解決策が実際の問題に適用できるかどうかわかりません。
肝心なのは、名前付きパイプはバッファリングされず、プラットフォーム固有のハックを使用しないとステータスを示すことができないということです。送信プロセスが受信者を待つか、受信プロセスが送信者を待ってぶらぶらします。
名前付きパイプよりも高度なメッセージ パッシング システムを使用する可能性があります。
名前付きパイプはファイルシステムに表示され、他のファイルと同じように読み書きできます。
$ ls -la /tmp/testpipe
prw-r--r-- 1 mitch users 0 2009-03-25 12:06 /tmp/testpipe|
名前付きパイプは、mkfifo または mknod によって作成されます。
$ mkfifo /tmp/testpipe
$ mknod /tmp/testpipe p
次のシェル スクリプトは、パイプから読み取ります。存在しない場合は最初にパイプを作成し、「終了」するまでループで読み取ります。
#!/bin/bash
pipe=/tmp/testpipe
trap "rm -f $pipe" EXIT
if [[ ! -p $pipe ]]; then
mkfifo $pipe
fi
while true
do
if read line <$pipe; then
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line
fi
done
echo "Reader exiting"