パイプを正しくバッファリング解除するには?

パイプを正しくバッファリング解除するには?

いろいろな答えに従おうとしています。これこれそしてこれスレッドがありますが、パイプはまだバッファリングされているようです。試してみる例は次のとおりです。

unbuffer sh -c 'echo -n test; sleep 1; echo; sleep 1; echo -n hello; sleep 1; echo' | grep .

上記のコマンドはすぐに印刷してtestから2回目に印刷し、hello1秒後にもう一度印刷する必要があります。代わりに1秒の遅延が発生し、testしばらくして二つ- 2 番目の遅延の後、helloコマンドは終了します。

ここで私が努力していることに注意してください。完全バッファリングを削除すると、--line-bufferedオプションはgrep役に立ちません。それでは、実際にこのパイプをどのようにバッファリング解除しますか?

ベストアンサー1

grep出力されますワイヤーパターンと一致するため、行全体を読み取るまで(またはファイルの終わり、最後の行が終わらない限り、動作は実装によって異なります)まで何も出力できません。

だから:

(echo -n foo; sleep 1; echo bar) | grep .

だからではないecho 出力をバッファリング。しかし、実際にはそうではありません。いったん終了したらどうなりますか?これは行末が待っているためですgrep(まもなく提供される予定で、2番目のファイルの終わりの文字が続きますecho)。

必要に応じて実行するには、1行あたりのタイムアウトを持つ行を読み取る必要があります(例:使用bash)。

(echo -n foo; sleep 1; echo bar) |
  while true; do
    TMOUT=0.1 IFS= read -r line; ret=$?
    if [ "$(kill -l "$ret")" = ALRM ]; then
      [ -n "$line" ] || continue
      ors=
    elif [ "$ret" -eq 0 ]; then
      ors=$'\n'
    elif [ -z "$line" ]; then
      break
    fi
    [[ $line =~ . ]] && printf %s "$line$ors"
  done

(少なくとも0.1秒ごとにループでパスを取得します)。

おすすめ記事