一時ファイルなしで別のコマンドが完了した後にのみ1つのコマンドを実行する方法はありますか?長期実行コマンドと出力フォーマットを指定し、カールを使用してHTTPサーバーに送信する別のコマンドがあります。実行すると起動し、commandA | commandB
サーバーcommandB
にcurl
接続してデータ転送を開始します。時間がかかりすぎてcommandA
HTTPサーバーがタイムアウトしました。私は私が望むことをすることができます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; }
出力の最初の行を読んでくださいsponge
。commandA
完了するまで表示されません。それから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