Как я могу одновременно создавать журналы с отметками времени и обработчики ошибок в BASH? - PullRequest
4 голосов
/ 16 июня 2020

Я пишу сценарий BASH, и две вещи, которые мне нужны, это:

  1. Предоставить файл журнала с меткой времени.
  2. Обработать ошибки.

Я обнаружил, что эти две цели противоречат друг другу.

Прежде всего, я использую команду ts для отметки времени записей журнала, например <a command/subscript> 2>&1 | ts '%H:%M:%S ' >> log. Обратите внимание, что мне нужно, чтобы все строки вывода любых индексов также имели временные метки. Это прекрасно работает ... пока я не попытаюсь обрабатывать ошибки с помощью кодов выхода.

За любой неудачной командой (завершается с кодом 1) немедленно следует команда ts, которая выполняется успешно (завершается с код 0). Это означает, что я не могу использовать коды выхода команд для обработки ошибок с переменной среды $?, потому что ts всегда является последней выполняемой командой и всегда имеет код выхода 0.

Вот оператор case, который я использую:

<command> 2>&1 | ts '%H:%M:%S ' >> log
case $? in
        0)
                echo "Success"
                ;;

        *)
                echo "Failure"
esac

1 Ответ

2 голосов
/ 16 июня 2020

Когда конвейер переднего плана возвращается, bash сохраняет значения статуса выхода его компонентов в переменную массива с именем PIPESTATUS . В этом случае вы можете использовать ${PIPESTATUS[0]} (или просто $PIPESTATUS; поскольку вас интересует первый компонент) вместо $?, чтобы получить значение статуса выхода <command>.

Доказательство концепции:

$ false | true | false | true
$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="1" [1]="0" [2]="1" [3]="0")
...