Bash
帶有 while-read 和管道掛起的 Bash tail -f
在 Bash 中,連接
tail -f
到read
循環的管道無限期地阻塞。while read LINE0 do echo "${LINE0}"; done < <( tail -n 3 -f /tmp/file0.txt | grep '.*' ) # hangs
刪除
-f
or| grep '.*'
,然後循環將迭代。以下不掛。
tail -n 3 -f /tmp/file0.txt | grep '.*'
是什麼導致了這種行為?
在 Bash 中是否有跟踪文件並讀取管道表達式的方法?
在管道中,
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
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}'