Bash

如果有 stderr,則在通知正文中使用 stderr 通知發送

  • August 11, 2022

假設我有一個類似的命令:

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執行的所有東西都共享它的標準輸入。有效地catifne. 和你的嘗試類似,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仍然解釋引號和反斜杠。)

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