読み込み中およびパイプの一時停止を含む Bash tail -f

読み込み中およびパイプの一時停止を含む Bash tail -f

Bashでは、ループtail -fにパイプを接続すると無期限にブロックされます。read

while read LINE0 
do 
    echo "${LINE0}"; 
done < <( tail -n 3 -f /tmp/file0.txt | grep '.*' ) 
# hangs

-fまたはを削除する| grep '.*'とループが繰り返されます。

次のアプローチはいいえ保留。

tail -n 3 -f /tmp/file0.txt | grep '.*' 

この動作の原因は何ですか?

Bashでファイルを追跡し、パイプ式を読み取ることはできますか?

答え1

パイプでは、grep出力がバッファリングされます。 GNU実装では、grep次のことができます--line-bufferedここのドキュメント);例えば:

tail -n 3 -f /tmp/file0.txt | grep --line-buffered '.*' |
  while IFS= read -r LINE0 
  do 
    printf '%s\n' "${LINE0}"
  done  

答え2

GregのWikiにはバッファリングに関する包括的な記事があります。https://mywiki.wooledge.org/BashFAQ/009

私に合った技術(Popos 20.04、Ubuntu 20.04)はstdbufラインバッファリングのためのものです。彼らの例:

tail -f logfile | stdbuf -oL grep 'foo bar' | awk ...

マイユースケース:

journalctl --output=json -t poke-stats -f |\
 stdbuf -oL jq -r '.__REALTIME_TIMESTAMP' |\
 stdbuf -oL awk '{print $1-last;last=$1}'

関連情報