Bash

帶有 while-read 和管道掛起的 Bash tail -f

  • February 9, 2022

在 Bash 中,連接tail -fread循環的管道無限期地阻塞。

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

刪除-for | 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}'

引用自:https://unix.stackexchange.com/questions/309453