我在 grep 過濾 make 輸出時遇到問題。尤其,
make target 2>&1 | grep -E --color=never "^make.*"
按預期工作,但以下內容不會在控制台上列印任何輸出:
make target 2>&1 | grep -E --color=never "^make.*" | cat
我錯過了一些明顯的東西嗎?為什麼第一個指令有輸出而第二個指令沒有輸出?是否與某種 IO 緩衝有關?或者我只是愚蠢?
[編輯]: cat
只是我想要使用的實際命令的最小測試案例佔位符。
[編輯]:這似乎不是 grep 的問題,因為將其替換為確認導致相同的行為。
[編輯]:cat 是佔位符的腳本:
#!/bin/bash
cat - \
| grep -E --color=never "^.*warning:.*|^.*error:.*|^make.*[Ee]rror.*|^make.*" \
| hilite.sh -r "^.*warning:.*" -f yellow -B \
| hilite.sh -r "^.*error:.*" -f red -B \
| hilite.sh -r "^make.*[Ee]rror.*" -f red -B \
| hilite.sh -r "^make.*" -f magenta
[編輯]:我認為這是一個緩衝/IO 問題。我將讓構建在 w/e 上運行,並查看它最終是否獲得所需的輸出!
答案1
可能是grep
偵測到它沒有寫入 TTY,因此它緩衝更多輸出,而不是在通常的行緩衝模式下運行(即您看到找到的每一行)。此行為更有效,因為它會減少write()
系統調用,但如果您是等待管道輸出的用戶,那麼它可能會有點誤導。
如果您使用的是 GNU grep
(並且基於您的 linux 標籤,我假設您是),請檢查該--line-buffered
選項,這將強制grep
在更熟悉的行緩衝模式下工作。從技術上講,這可能會降低效能grep
(如手冊頁所述),但由於您正在查看即時建置的輸出,我懷疑它在這方面會產生任何影響。
答案2
不確定您的命令應該做什麼,cat 任何檔案名稱中包含 make.* 的檔案嗎?
嘗試更改cat
為xargs cat
?
答案3
您可以嘗試嘗試unbuffer
,例如
make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat