Bashプロセスの置き換えで標準出力の最初の行をキャプチャする方法は?

Bashプロセスの置き換えで標準出力の最初の行をキャプチャする方法は?

次のbashブロックを使用していますが、期待される出力の最初の行は印刷されません。

    exec 3< <(python3 -m http.server)
    while true; do
            read -t 2 line
            echo "reading..."
            echo "$line"
    done <&3

起動時にpython3 -m http.server1行を印刷しServing HTTP on 0.0.0.0 port 8000ますが、上記のコードはその行を印刷しません。その後、Pythonはそれを印刷し、GET要求が発生するたびに印刷します。 Bashに最初の行がないのはなぜですか?

私の目標は、これをスクリプトに入れ、echo呼び出しをリダイレクトされたプロセスのテストに置き換えることによってブートが完了したことを示すことです。その後、ループを中断してスクリプトを終了します(ブートが完了するまでスクリプトの実行をブロックします)。バックグラウンドでリダイレクトされたプロセスは続行されます。http.serverこれは私のテストケースです。

答え1

その理由は次のとおりです。

  • Pythonはパイプまたはファイルにリダイレクトされると出力バッファリングを実行します。
  • http.server最初の行をstdoutに書き込み、stderrのログにアクセスします。

以下を行う必要があります。

exec 3< <(python3 -u -m http.server 2>&1)

目標について言えば、特定の出力を得た後でもスクリプトはパイプから読み続ける必要があるようです。パイプへの出力がブロックされると、子プロセスの実行が停止するためです。

関連情報