如果有 stderr,則在通知正文中使用 stderr 通知發送
假設我有一個類似的命令:
foo() { echo a echo b >&2 echo c echo d >&2 }
我使用以下命令在終端中處理標準輸出,但通過 notify-send 發送錯誤
foo 1> >(cat) 2> >(ifne notify-send "Error")
我遇到的問題是,我想將 stderr(在這種情況下
b d
)視為通知發送主體。我努力了:
foo 1> >(cat) 2> >(ifne notify-send "Error" "$(cat)") foo 1> >(cat) 2> >(ifne notify-send "Error" "$(</dev/stdin)")
沒有任何工作。這裡有什麼解決方案?
隨著你的嘗試,
"$(cat)"
你幾乎就在那裡,但你需要cat
從 閱讀ifne
,而不是閱讀ifne
。在 的情況下
ifne notify-send "Error" "$(cat)"
,cat
會從同一流ifne
中讀取,但不會同時讀取。處理這部分程式碼的shellifne
只能在cat
退出後執行(因為只有這樣它才知道$(cat)
應該擴展為什麼,即fine
應該得到什麼參數)。退出後cat
,流已經耗盡,並且ifne
將其輸入視為空。這是一種類似使用的
cat
讀取方式ifne
:foo 2> >(ifne sh -c 'exec notify-send "Error" "$(cat)"')
(我不確定你的目的是什麼
1> >(cat)
。我跳過了。)這裡
ifne
將其輸入中繼到它(有條件地)執行的任何內容的標準輸入。它是sh
,但是它sh
執行的所有東西都共享它的標準輸入。有效地cat
從ifne
. 和你的嘗試類似,exec notify-send
只能在cat
退出後執行;因此,即使notify-send
嘗試從其標準輸入中讀取,cat
也會首先消耗所有內容。如果通過的數據過多,此方法可能會失敗
cat
。參數列表不能任意長。並且因為cat
只會在退出後foo
退出,所以該方法適用於foo
退出並且不會向其標準錯誤生成太多消息。對於偶爾會產生一行錯誤的長時間執行,使用
xargs
代替可能是一個好主意。這是這樣的一個例子:$(cat)``foo``foo
foo() { echo a echo b >&2 sleep 10 echo c echo d >&2 sleep 20 }
在這種情況下,上述解決方案不一定很好
foo
(試試看)。有了xargs
它就不同了。foo
甚至可以無限期地執行,並且您將立即收到錯誤通知(一次一行)。如果您xargs
支持--no-run-if-empty
(-r
) 那麼您不需要ifne
. 這是一個範例命令xargs
:foo 2> >(xargs -r -I{} notify-send "Error" {})
(請注意,這
xargs
仍然解釋引號和反斜杠。)