別のコマンドにパイプする前に、コマンド出力を完全にバッファリングしますか?

別のコマンドにパイプする前に、コマンド出力を完全にバッファリングしますか?

一時ファイルなしで別のコマンドが完了した後にのみ1つのコマンドを実行する方法はありますか?長期実行コマンドと出力フォーマットを指定し、カールを使用してHTTPサーバーに送信する別のコマンドがあります。実行すると起動し、commandA | commandBサーバーcommandBcurl接続してデータ転送を開始します。時間がかかりすぎてcommandAHTTPサーバーがタイムアウトしました。私は私が望むことをすることができますcommandA > /tmp/file && commandB </tmp/file && rm -f /tmp/file

好奇心に一時ファイルなしでこれを行う方法があるかどうかを知りたいです。試してみましたが、mbuffer -m 20M -q -P 100カーリングプロセスはまだ最初から始まります。 MbufferはcommandA実際のデータ転送が完了するのを待ちます。 (データ自体は最大数百キロバイトです。)

答え1

これは他のいくつかの答えと似ています。 "moreutils"パッケージがある場合は、このspongeコマンドが必要です。努力する

commandA | sponge | { IFS= read -r x; { printf "%s\n" "$x"; cat; } | commandB; }

このコマンドは、入力全体が読み取られるまで出力書き込みを開始しないことを除いて、デフォルトではパススルーspongeフィルタ(例)です。catつまり、データを「吸収」してから(スポンジのように)圧着すると、データが放出されます。したがって、これはある意味で「トリック」です。データ量が大きい場合、sponge一時ファイルはほぼ確実に使用されます。しかし、それはあなたには見えません。一意のファイル名を選択して後で整理するなど、家事を心配する必要はありません。

{ IFS= read -r x; { printf "%s\n" "$x"; cat; } | commandB; } 出力の最初の行を読んでくださいspongecommandA完了するまで表示されません。それからstartを実行しcommandB、最初の行をパイプに書き込み、呼び出しを介して残りのcat出力を読み取り、パイプに書き込みます。

答え2

commandAパイプラインのコマンドは同時に開始され、後で使用するために出力をどこかに保存する必要があります。変数を使用すると、一時ファイルを回避できます。

output=$(command A; echo A)
printf '%s' "${output%%A}" | commandB

答え3

私はこの問題を解決できる標準のUNIXユーティリティを知りません。 1つのオプションは、awk累積commandA出力を使用して、commandB次のように一度にフラッシュすることです。

commandA  | awk '{x = x ORS $0}; END{printf "%s", x | "commandB"}'

awk文字列は入力から作成されるため、多くのメモリを占有できます。

答え4

別のオプションは食べ物;

| tac | tac

関連情報