Grep 無法輸出到管道?

Grep 無法輸出到管道?

我在 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.* 的檔案嗎?

嘗試更改catxargs cat

答案3

您可以嘗試嘗試unbuffer,例如

make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat

相關內容