Shell

如何正確取消緩衝管道?

  • August 18, 2017

我試圖在thisthisthis執行緒中遵循各種答案,但我的管道仍然出現緩衝。這是一個範例嘗試:

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

上面的命令應該立即 print test,然後在第二次 print 之後hello,再過一秒鐘結束。相反,我得到一秒鐘的延遲,然後test,然後,在秒鐘的延遲之後,hello使用命令退出。

請注意,在這裡我試圖完全擺脫緩衝,並且--line-buffered選項grep無濟於事。那麼,我如何真正取消緩衝這條管道呢?

grep將輸出與模式匹配的,因此在讀取整行(或文件末尾,如果最後一行未終止,則行為因實現而異)之前,它無法輸出任何內容。

所以在:

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

這不是因為echo 緩衝了它的輸出。它沒有。它怎麼可能,一旦它終止了?這是因為grep正在等待行尾(即將到來,緊隨其後的是帶有第二個的文件結束echo)。

要執行您似乎想要的操作,您需要為每一行讀取帶有超時的行,例如 (with 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 秒通過一次循環)。

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