Как перенаправить вывод и выйти при сбое команды?

Как перенаправить вывод и выйти при сбое команды?

Вот как я регистрирую stdout и stderr в своих скриптах (обычно cronjobs):

#!/bin/bash
mylog() {
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1"
}
(
mylog 'start'

some-command || mylog 'error' && exit 1

mylog 'end'
) >> /var/log/my-log.log 2>&1

В некоторых скриптах я использую return вместо exit и все работает нормально, но теперь он говорит, что я не могу использовать return, если не включу скрипт с src или не использую его в функции. Поэтому я изменил его на exit, но проблема в том, что он ничего не регистрирует, похоже, он останавливает перенаправление вывода >>. Другая проблема в том, что я не смогу включить его позже с src, потому что я хочу остановить только этот скрипт, а не все.

Я использую перенаправление вывода, потому что хочу регистрировать все, даже если не произошло никакой ошибки. А иногда команды даже не возвращают правильные коды выхода, так что я не могу этому доверять.

Так как же мне «вернуться» при ошибке? Я знаю о «set -e», но я предпочитаю иметь больше контроля над тем, когда останавливать скрипт.

Есть предположения?

решение1

Я не могу объяснить поведение, которое вы испытываете, но вот возможное решение:

#!/bin/баш
мойлог() {
    echo "[$(дата '+%Г-%м-%д %Ч:%М:%С')] $1"
}

мой основной() {
    (
        мой журнал 'старт'

        какая-то-команда || mylog 'error' && возвращает 1

        мой лог 'конец'
    ) >> /var/log/my-log.log 2>&1
}

мой основной

В качестве альтернативы можно удалить перенаправление из mymainопределения функции и поместить его в mymainвызов функции:

mymain >> /var/log/my-log.log 2>&1

(Тогда вы также сможете удалить скобки из mymainопределения функции.) В качестве альтернативы, поскольку вы хотите, чтобы ввод-вывод был перенаправлен длявесьскрипт, вы можете разбить перенаправление на части, кроме операторов действий:

exec >> /var/log/my-log.log
исполнитель 2>&1
мой основной

Поскольку я не понимаю, почему ваш подход терпит неудачу, я не могу объяснить, почему любой из вышеперечисленных вариантов с большей вероятностью будет работать так, как хотелось бы. Однако, это немного разные способы сделать одно и то же, и этого может быть достаточно. Кстати, я изменил `date …`на $(date …)just for general cause; я не думаю, что это как-то связано с вашей проблемой.

решение2

А как насчет использования screenкоманды в Linux? Это было бы трюком, если только вы не настроены программировать решение самостоятельно.

Связанный контент