web-dev-qa-db-ja.com

パイプなどでコマンドのループを構築することは可能ですか?

これまでのところ、最後のコマンドに到達するまで、あるコマンドのstdoutを次のコマンドのstdinに接続する一連のコマンドを接続する方法として、パイピングメカニズムを知っています。これは、そのstdoutをディスプレイまたはファイルに接続します。

ただし、コマンドからループを作成して、最後のコマンドのstdoutを最初のコマンドのstdinに接続し、おそらくteeを使用して、特定の出力の変化する値を表示することは可能でしょうか?

3
sharkant

確かに、ループを作成して変数を使用するだけで可能です。

while true; do
    a=$(echo "$a" | grep "Hey" | cut -d" " -f2 | tee -a log)
done

これにより、最初に使用される最後の出力が保存されます。

2
ADDB

そこにあるすべてのシェルについてはわかりませんが、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が何を示しているか見てみましょう。 catxargsの両方のアクティビティがかなり多いはずです。

また、前と同じように、パイプラインをドレインすると、ターミナルに多くのxsが表示され、パイプラインがブロックされます。

なぜパイプラインが空になるのか、それは有効な質問です。 catコマンドがターミナルでコミットされ、回路に何も残っていないのはなぜですか。私はこれを知りません。

6
user147505

いいえ、それは不可能です。少なくとも、深刻なファイル記述子のトリック、または ADDBが彼の回答に示されている のようなループがないわけではありません。

自己給電循環パイプラインの構文を実装することを保証するのに十分な既存の現実の問題はありません。パイプラインが「終了」と見なされる時期、その終了ステータス、およびそれを確実にする方法を決定する際の問題を確認できます。ブロッキングではありません。

現時点で私が考えることができるアプリケーションのタイプは、数値解析の分野、またはエラー推定値が特定のポイントを下回るまで反復法を使用して数値解を洗練する他のいくつかの計算分野です。

これらのタイプの問題には、浮動小数点演算(多くの場合、高精度)が必要です。これは、ほとんどのシェルではサポートされていません。これらの問題は、一般に、シェルが提供するものよりも高速な実行環境を必要とします。

2
Kusalananda