待たずに名前付きパイプを猫にする方法

待たずに名前付きパイプを猫にする方法

名前付きパイプには何もなく、次のことを行います。

cat my_named_pipe

データが届くまで待ちます。読み取るデータがない場合は、フラグを使用してすぐに終了できますか?それともcat以外のコマンドを使用できますか?

私も次のことを試しました。

read val < "$my_named_pipe";

しかし、これはまた、次のデータの塊を待つでしょう。 fifoが空であれば待ちたくありません。

答え1

ライターがない停止を防ぐにはcat(この場合はFIFOを開かずに停止する場合)、次のことを実行できます。

cat 0<> "$my_named_pipe" <"$my_named_pipe"

最初のリダイレクトは読み取り+書き込みモードで開きます。このモードは、ほとんどのシステムで作成者やリーダーがなくてもパイプをブロックまたはインスタンス化しません。その後、2番目のオープン(今回は読み取り専用)は、少なくとも1つの作成者(自己)を持っているため、ブロックされません。

デフォルトのfdが0から1に変更されたksh93の最新バージョンでのみ0必要です。<>

また、シェル組み込みではksh93動作しません。たとえば、ksh93の前または後に呼び出すと(私の考えでは)、stdinの古いターゲットを別のファイル記述子に保存してパイプを開いたままにします。以下を作成してこの問題を解決できます。catksh93/opt/ast/bin/bin$PATHbuiltin cat<"$my_named_pipe"

cat 3<> "$my_named_pipe" <"$my_named_pipe" 3<&-

(これが意図をより明確に伝えると思うかもしれません)

<>パイプの他のリーダーもFIFOのロックを解除します。

作成者が数人いる場合catでも、作成者のすべての出力を読み、パイプの終わりが閉じるまで待つ必要があります。 GNUと同様に、非ブロックモードでパイプを開くことができますdd

dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer

パイプにデータがある限り、パイプからデータを読み取り、終了します。

dd: error reading 'fifo': Resource temporarily unavailable

もうリーダーがなく、他のリーダーがロック解除されないとエラーが発生しますが、これはddパイプへの書き込みが読み取り可能なものより遅い場合は一部の作成者の出力を見逃す可能性があります。

別のアプローチは、一定期間入力がない場合にタイムアウトを実行することです(例:socats-Tオプションを使用)。

socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe"

1秒間パイプから何も出ないと抜けます。

答え2

非常に簡単な方法は、catデータがあるかどうかにかかわらず、fifoを読んだ直後に終了することです。以下を使用してこれを実行できますtimeout

timeout 2 cat my_named_pipe

上記では、timeoutcatを強制終了する前に2秒ほど待ちます。実行時に名前付きパイプにバッファリングされたコンテンツがある場合は、cat標準出力として印刷されます。

おそらく最もクリーンなソリューションではありませんが、作業を完了できます。

お役に立てば幸いです。

関連情報