Селективное подавление выходного кода выхода

У меня есть программа foo , которая может

  1. успеха;
  2. print Ошибка и не работает
  3. или распечатать что-то еще и сбой.

I have a short script foo && bar run by cron. The case 2 is almost always the case, so my mailbox gets flooded with "Failure" messages from cron.

Я хочу прекратить получать уведомления «Отказ», сохраняя уведомления об успехах и сбоях с другими сообщениями.

Я попытался написать функцию bash wrap_foo , которая ведет себя как foo , но не печатает Failure . Что-то вроде этого:

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

Но он всегда терпит неудачу, поэтому bar не выполняется, если выполняется foo .

Один из способов, похоже, - тест равенства на $ (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
}

Может ли оно быть короче?

0
nl ja de
foo изменяет файлы на диске. bar выполняет другое действие с теми же файлами и должен запускаться только после того, как foo преуспел. bar , если они должны быть отправлены почтой. Подумайте о foo и bar , поскольку две команды выполняются последовательно с set -e .
добавлено автор nponeccop, источник
Исправлены и добавлены тесты. $ 1 | grep -vF Ошибка проходит 1, но не 2 и 3.
добавлено автор nponeccop, источник
проходит 1 и 3, но не 2, извините :(
добавлено автор nponeccop, источник
В чем именно заключается цель bar в вашем примере?
добавлено автор Perleone, источник
Разве это не должно быть foo && bar ?
добавлено автор Perleone, источник

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

это немного немного короче, но нет никакого временного файла.

0
добавлено
Существует недостаток, что длинный вывод будет занимать память.
добавлено автор nponeccop, источник