【问题标题】:Selective suppression of output preserving exit code选择性抑制输出保留退出代码
【发布时间】:2013-01-29 09:07:28
【问题描述】:

我有一个foo 程序,可以

  1. 成功;
  2. 打印Failure 失败;
  3. 或打印其他内容并失败。

我有一个由 cron 运行的简短脚本 foo && bar。情况 2 几乎总是如此,所以我的邮箱被来自 cron 的“失败”消息淹没了。

我想停止接收“失败”通知,保留来自成功和失败的通知以及其他消息。

我尝试编写一个 bash 函数 wrap_foo,它的行为类似于 foo,但不打印 Failure。像这样的:

wrap_foo() {
    foo | grep -vF "Failure"
}
wrap_foo && bar

但它总是失败,所以如果foo 成功,bar 不会被执行。

一种方法似乎是对$(foo) 进行相等性测试,但我想尽可能避免它,因为输出可能很长。

我应该使用mktemp 并在那里重定向foo 输出吗?如果没有更简单的方法,我该如何保存foo失败状态并在删除临时文件后恢复它?

这是一个测试套件:

foo_failed() {
        echo Failed
        false
}

foo_false() {
        echo Error
        false
}

foo_true() {
        echo Something
        true
}

bar() {
        echo bar
        true
}

wrap_foo()
{
        $1 | grep -vF Failed
}

run() {
        wrap_foo $1 && bar
}

echo should not write anything
run foo_failed
echo should write Error
run foo_false
echo should write Something then bar
run foo_true

这是一个带有临时文件的解决方案:

wrap_foo()
{
        T=$(mktemp)
        $1 >$T
        X=$?
        grep -vF Failed $T
        rm $T
        return $X
}

可以再短一点吗?

【问题讨论】:

  • 在您的示例中,bar 的确切用途是什么?
  • foo 更改磁盘上的文件。 bar 对相同的文件执行另一个操作,并且必须在 foo 成功后运行。 bar 输出也必须通过邮件发送。将foobar 想象为与set -e 依次运行的两个命令。
  • 不应该是foo && bar吗?
  • 修复并添加了测试。 $1 | grep -vF Failed 通过 1 但不通过 2 和 3。
  • 通过 1 和 3 但没有通过 2,抱歉 :(

标签: shell error-handling cron grep


【解决方案1】:

使用您的测试套件,我将wrap_foo() 函数修改为以下内容,这似乎可行:

wrap_foo()
{
        foooutput=$($1)
        foostatus="$?"
        echo "$foooutput" | grep -vF Failed
        return "$foostatus"
}

输出:

should not write anything
should write Error
Error
should write Something then bar
Something
bar

它只是有点短,但不涉及临时文件。

【讨论】:

  • 长输出会占用内存。
猜你喜欢
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 2019-07-10
  • 2015-08-28
  • 1970-01-01
  • 2016-03-07
相关资源
最近更新 更多