如果存在 stderr,则在通知正文中使用 stderr 进行通知发送

如果存在 stderr,则在通知正文中使用 stderr 进行通知发送

假设我有这样的命令:

foo() {
    echo a
    echo b >&2
    echo c
    echo d >&2
}

我使用以下命令在终端中处理标准输出,但通过通知发送发送错误

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)")

什么都不起作用。这里有什么解决办法呢?

答案1

通过您的尝试,"$(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.和你的try类似,exec notify-send只能在cat退出后执行;因此,即使notify-send尝试从其标准输入中读取,cat也会首先消耗所有内容。

如果传递的数据过多,此方法可能会失败cat。参数列表不能任意长。并且因为cat只有在退出后才会退出foo,所以该方法适用于foo退出并且不会向其 stderr 生成太多消息。

对于长时间运行来说,使用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仍然解释引号和反斜杠。)

相关内容