Shell
如何正確取消緩衝管道?
我試圖在this、this和this執行緒中遵循各種答案,但我的管道仍然出現緩衝。這是一個範例嘗試:
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 秒通過一次循環)。