bash скрипт перенаправление ошибок в файл

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

Ответить
safronowmax
Сообщения: 103

bash скрипт перенаправление ошибок в файл

Сообщение safronowmax »

Здравствуйте, подскажите пожалуйста, есть bash скрипт и нужно писать в лог, успешно или нет отработала команда или нет в таком формате:
"Команда отработала успешно"
либо
"Команда завершилась с ошибкой". И далее перенаправлять поток ошибок в этот же лог файл
Все работает, за исключением одного момента. У меня сейчас получается сначала идет перенаправление потока ошибок в файл, а далее уже вывод сообщения "Команда завершилась с ошибкой". Не могу понять, как сделать наоборот, чтобы сначала выводилось сообщение, а потом уже сама ошибка

Вот мой скрипт:

Код: Выделить всё

# лог файл
LOG_FILE=/log/my.log
# выполняем нужную нам команду
ls -l skldjflkjsdf 2>> $LOG_FILE
# пишем в лог, успешно завершилась команда или нет
if [ $? -eq 0 ]; then
echo "Команда отработала успешно" >> $LOG_FILE
else echo "завершилась ошибкой" > $LOG_FILE
fi
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 901
ОС: debian, fedora (i3-wm)

Re: bash скрипт перенаправление ошибок в файл

Сообщение olecya »

safronowmax писал(а):
28.10.2022 09:23
else echo "завершилась ошибкой" > $LOG_FILE
Вам необходимо чтобы лог затирался при возникновении ошибки во время очередного запуска? Или это опечатка вместо перенаправления с добавлением? >>
Добавлено (14:28):
Ладно, кажется поняла. Довольно непросто написать что-то не вмешиваясь в поток.

Код: Выделить всё

LOG_FILE=/log/my.log
ls -l skldjflkjsd 2> >(sed '1i\Получи ошибку' >>$LOG_FILE) &&
    echo Команда отработала успешно >> $LOG_FILE
Добавлено (14:51):
Если в скрипте много команд можно объединить их в блок, а стандартный поток ошибок перенаправить в файл подобным образом:

Код: Выделить всё

exec 2> >(sed '1i\Получи ошибку' >> $LOG_FILE)
ls &&
    my_prog &&
        echo "Скрипт отработал успешно" >> $LOG_FILE
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 901
ОС: debian, fedora (i3-wm)

Re: bash скрипт перенаправление ошибок в файл

Сообщение olecya »

Интересно, если напрямую перенаправлять в лог то сообщение из ловушки приходит после ошибки, но если через cat или sed то в начале. Надо полагать, порядок может нарушаться:

Код: Выделить всё

#!/bin/bash
set -e
LOG_FILE=/log/my.log
trap "echo Получи ошибку >>$LOG_FILE" ERR 
{
  echo hi
  cd .lksdjfls
  cat tust.shlkdjlskdj
  echo bye
} 2> >(cat >>$LOG_FILE)
echo Команда отработала успешно >> $LOG_FILE
Спасибо сказали:
MiK13
Сообщения: 1180
ОС: Linux Debian

Re: bash скрипт перенаправление ошибок в файл

Сообщение MiK13 »

safronowmax писал(а):
28.10.2022 09:23
Здравствуйте, подскажите пожалуйста, есть bash скрипт и нужно писать в лог, успешно или нет отработала команда или нет в таком формате:
"Команда отработала успешно"
либо
"Команда завершилась с ошибкой". И далее перенаправлять поток ошибок в этот же лог файл
Все работает, за исключением одного момента. У меня сейчас получается сначала идет перенаправление потока ошибок в файл, а далее уже вывод сообщения "Команда завершилась с ошибкой".
Естественно. Так как протокол формируется во время работы программы и после её завершения формируется код ошибки.
safronowmax писал(а):
28.10.2022 09:23
Не могу понять, как сделать наоборот, чтобы сначала выводилось сообщение, а потом уже сама ошибка
Вот мой скрипт:

Код: Выделить всё

# лог файл
LOG_FILE=/log/my.log
# выполняем нужную нам команду
ls -l skldjflkjsdf 2>> $LOG_FILE
# пишем в лог, успешно завершилась команда или нет
if [ $? -eq 0 ]; then
echo "Команда отработала успешно" >> $LOG_FILE
else echo "завершилась ошибкой" > $LOG_FILE
fi
Чтобы сообщение было в начале файла, его надо вставить с помощью любого текстового редактора.
Так как надо, чтобы сообщение записывалось автоматически во время работы скрипта, можно использовать потоковый редактор sed.
То есть вместо строк

Код: Выделить всё

echo "Команда отработала успешно" >> $LOG_FILE
else echo "завершилась ошибкой" > $LOG_FILE
записать строки

Код: Выделить всё

sed -i 1i"Команда отработала успешно"  $LOG_FILE
else sed -i 1i"завершилась ошибкой"  $LOG_FILE
Правда, надо учесть, что если данный скрипт используется не один раз, а сообщение об ошибке добавляется в файл протокола (>>, а не >) то сообщения о результатах работы команды будут всегда добавляться в начало файла, что неверно. Чтобы этого не было, можно в начале вывод команды направить во временный файл, потом добавить в его начало строку о результате завершения команды, а потом содержимого этого временного файла добавить в основной файл протокола. При этом можно обойтись и без прогрограммы sed
Спасибо сказали:
Ответить