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}'