Bashスクリプト内のコマンドグループ(中括弧)の出力バッファリングを防止する

Bashスクリプト内のコマンドグループ(中括弧)の出力バッファリングを防止する

中かっこで囲まれた一連のコマンドを含むbashスクリプトがあります{ ... }。このグループにはいくつかの初期echoコマンドが含まれています。一輪。各反復では、ループはさまざまなタスクを実行します。遅いコマンド(基本的にcurl追加の解析を含む)各反復はネットワークのやり取りのために遅いですが、私が知っている限り、コマンド自体はジョブを終了して残すときにバッファリングの問題があってはならないという行(Pythonコード)を印刷します。

命令セット全体がパイプで接続されpython -u(確認するためにこれも試みましたtail -f)、明らかにループ全体が何でpython -uあれ、読み込み前に実行または読み込まれますtail -f

バッファリングを解放する方法を知っています(可能な場合)。一つ命令はいろいろなツールに似ていますstdbufが、こちらの向こうの命令で問題が発生するのではなく、命令のグループ化で問題が発生しているようで、ここでは役に立たないようです。

どのようなヒントがありますか?

答え1

(今後の読者のための注意:ここで怒っているのは、質問に対するものではなく、私が答えようとしている間に犯した間違いとそれに必要ないくつかの編集についてです。)

ああ、残念です。問題はtail -f次のとおりです。

#!/bin/bash
printf 'hi\n'
{
    for i in 1 2 3 4; do
        sleep 0.5
        /bin/echo $i
    done;
} | cat
printf 'bye\n'

これはパイプラインやグループではありません。それはtail。それは私たち自身の尾を追うようなものです!

そのため、tail -f何らかの理由で直ちに出力されないため失敗します。なぜ失敗したのかわかりませんが、python -uスクリプトには何もないと思います。一度試してみてくださいunbuffercat少なくともスクリプトを試して、この場合はバッファリングが発生しないことを確認してください。


将来の読者がコメントを理解できるように、最初に失敗した試みは意図的にここに残しました。

このスクリプトは、あなたが経験しているのと同じ種類のバッファリングの問題を表します。

#!/bin/bash
printf 'hi\n'
{
    for i in 1 2 3 4; do
    sleep 0.5
    printf '%s\n' $i
    done;
} | tail -f
printf 'bye\n'

そうではありません。グループ内の出力はstderrにリダイレクトされ、グループ全体のstderrがコマンドにパイプされます。標準エラーなのでバッファリングされません。

#!/bin/bash
printf 'hi\n'
{
    for i in 1 2 3 4; do
    sleep 0.5
    printf '%s\n' $i 1>&2
    done;
} |& tail -f
printf 'bye\n'

Wang Hongqinの回答で採用この問題。難しいのは、明示的なコマンドの代わりに中かっこを使用してパイプをバッファリング解除する方法を見つけることです。リダイレクトを機能させるには、しばらく操作する必要がありました。

答え2

あなたがしなければならないことは次のとおりです。

{   stdbuf -o0 curl ...
    stdbuf -o0 whatever ...
}|  tail -f

curl...これは動的にリンクされたアプリケーションで動作しますが、独自のアプリケーションが含まれていると確信しています。バッファリング解除一種のスイッチ。

関連情報