これまでのところ、パイプ メカニズムは、最後のコマンドに到達するまで、1 つのコマンドの stdout を次のコマンドの stdin に接続し、その stdout をディスプレイまたはファイルに接続することによって、一連のコマンドを接続する方法であるとわかっています。
しかし、コマンドのループを作成して、最後のコマンドの stdout を最初のコマンドの stdin に接続し、tee を使用することで、特定の出力の変化する値を表示することは可能でしょうか?
答え1
すべてのシェルについて確信はありませんが、Bash では可能です。ただし、名前のないパイプでは不可能です。つまり、シンボルでは不可能です|
。ただし、名前付きパイプを作成すると、次のようになります。
mkfifo fifo
次に、それを使用できます。
<fifo cat | cat >fifo &
現在、パイプラインはバックグラウンドで動作していますが、何もしません。ただし、パイプラインの外部からパイプにデータを入力すると、次のようになります。
echo x >fifo
パイプラインはブロックを解除し、永久に継続します。または、パイプを空にするまで継続します。
cat fifo
出力は 1 回表示されます。
x
これをもう少し複雑にするには、パイプラインは次のようになります。
<fifo cat | xargs -I@ echo @x >fifo &
したがって、各反復で出力に が追加されますx
。もちろん、反復が開始されるとすぐに追加されます。つまり、パイプのブロックが解除されるとすぐに、つまり、読み取るものが存在するとすぐに追加されます。以前と同様に、これは手動で開始できます。
echo x >fifo
では、何が表示されるか見てみましょう。とtop
の両方で、かなり多くのアクティビティがあるはずです。cat
xargs
x
そして、前と同じように、パイプラインをドレインすると、ターミナルに多数の が表示され、パイプラインがブロックされます。
なぜパイプラインが空になるのか、というのは正当な疑問です。cat
ターミナルでコマンドがコミットされても回路に何も残らないのはなぜでしょうか。これはわかりません。
答え2
確かに、ループを作成して変数を使用するだけで可能です。
while true; do
a=$(echo "$a" | grep "Hey" | cut -d" " -f2 | tee -a log)
done
最後の出力を保存し、最初に再度使用します。
答え3
既存の回答によると、ループパイプラインは、名前付きパイプ(msfifo(1))。しかし、Cでも同様にできます。例えば、私の非常にシンプルな実装、プロセスが終了するのを待つことすらしませんでした。
この情報が役に立つことを願っています。