Вопрос или проблема
У меня есть следующий шаблон сценария, который я пишу для использования LFTP, чтобы зеркалировать удаленные файлы в локальную папку для клиентов. Если зеркалирование не удастся, я хотел бы, чтобы он отправил электронное письмо с выводом, который был зарегистрирован (но не сам файл журнала, так как он может быть довольно длинным). Как лучше всего отправлять вывод вместо этого?
#! /bin/bash
# Информация о клиенте
client=example
data=/home/clients/$client/data
log=/home/clients/$client/log
# Создание каталогов
mkdir -p $data $log
# Настройки LFTP
protocol="sftp://"
host="ftp.example.com"
user="example"
pass="123abc"
remote=/Outbound
command="mirror --verbose --continue $remote $data"
# Вывод в лог
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>>$log/$client.log 2>&1
# Начало импорта | Рекурсивное зеркалирование удаленного в данные
timestamp="$(date +"%m-%d-%Y@%T")"
echo "*** Время $timestamp ***"
echo "Начало импорта $client."
lftp -u $user,$pass $protocol$host <<EOF
set net:timeout 5
set net:max-retries 2
set net:reconnect-interval-base 5
$command
bye
EOF
# Сохранить статус выхода импорта
import_exit_status=$?
# Отправка уведомления, если импорт не удался
if [ $import_exit_status -ne 0 ]; then
/usr/sbin/sendmail "[email protected]" <<EOF
subject:$client Импорт не удался
from:notifications@host
Импорт не удался по следующим причинам:
$import_exit_status
EOF
else
echo "Импорт завершен."
echo ""
fi
exit 0
Вероятно, наиболее совместимый способ — использовать команду mail
.
echo "Последние строки:\n $(tail -n 30 client.log)" | \
mail --subject "$(hostname -f): Импорт не удался" [email protected]
Для более длинного вывода можно использовать вложение:
mail -s "Ошибка" --attach=debug.log [email protected]
Это предполагает, что вы настроили MTA, Mail Transfer Agent. Существует несколько альтернатив, поэтому такой скрипт может работать с различными дистрибутивами. Пакет должен создать символическую ссылку на /usr/bin/mail
, так что в вашем скрипте вам не нужно полагаться на конкретную реализацию. Просто несколько примеров:
sendmail
exim4
postfix
msmtp
s-nail
/mailx
Например, существует небольшой s-nail, который должен быть доступен во многих дистрибутивах (Alpine, Arch, Debian, CentOS, Fedora, Homebrew, OpenBSD, …)
Поскольку скрипт может завершиться ошибкой на любой команде, было бы удобнее, если бы вы переместили логику в функции:
#!/bin/bash
run_import() {
echo "Начало импорта $client."
lftp ... || return 1
return 0
}
report() {
echo "Последние строки:\n $(tail -n 30 client.log)" | \
mail --subject "$(hostname -f): импорт завершился ошибкой с кодом $1" \
[email protected]
return 0
}
run_import || report $?
Ответ или решение
Отправка электронной почты с выводом ошибок после сбоя сценария является важной и полезной практикой для мониторинга работоспособности автоматизированных процессов. Рассмотрим, как можно отправить электронное письмо с логами скрипта на Bash, если операция LFTP не удалась.
Как отправить уведомление по электронной почте с выводом логов при сбое скрипта
Ваш текущий сценарий использует LFTP для зеркалирования удаленных файлов в локальную папку. Чтобы отправить электронное письмо с деталями ошибок, вам необходимо реализовать отправку с содержанием последних строк из файла логов.
Шаги реализации:
-
Настройка Средства Отправки Почты (MTA):
Убедитесь, что на вашей системе установлен и настроен почтовый агент (MTA), такой какsendmail
,postfix
, илиmsmtp
. Это позволит вашему скрипту отправлять электронные письма. Например,sendmail
может быть установлен с помощью пакетного менеджера вашей операционной системы. -
Изменение Вашего Скрипта:
По умолчанию сценарий записывает весь вывод в файл лога $log/$client.log
. Вам нужно изменить скрипт таким образом, чтобы в случае сбоя операции LFTP, отправлялось уведомление с последними строками лога.
#!/bin/bash
# Информация о клиенте
client=example
data=/home/clients/$client/data
log=/home/clients/$client/log
# Создание директорий
mkdir -p $data $log
# Настройки LFTP
protocol="sftp://"
host="ftp.example.com"
user="example"
pass="123abc"
remote=/Outbound
command="mirror --verbose --continue $remote $data"
# Перенаправление вывода в лог
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>>$log/$client.log 2>&1
# Начало процесса импорта
timestamp="$(date +"%m-%d-%Y@%T")"
echo "*** Время: $timestamp ***"
echo "Инициализация импорта для клиента $client."
lftp -u $user,$pass $protocol$host <<EOF
set net:timeout 5
set net:max-retries 2
set net:reconnect-interval-base 5
$command
bye
EOF
# Получение статуса завершения импорта
import_exit_status=$?
# Отправка уведомления в случае сбоя
if [ $import_exit_status -ne 0 ]; then
echo -e "Последние строки лога:\n$(tail -n 30 $log/$client.log)" | \
mail --subject "$(hostname -f): Сбой импорта для $client" [email protected]
else
echo "Импорт завершен успешно."
fi
exit 0
Важные моменты:
- Настройка почтового агента (MTA) обязательно: для отправки почты необходимо корректно настроенное почтовое соединение.
- Функции и структуризация: вы можете улучшить читаемость скрипта, обернув логику в функции, как предложено в изначальном описании.
- Альтернативные средства: использование команд
mailx
илиs-nail
может предоставить более расширенные возможности отправки писем, такие как поддержка вложений или конфиденциальных тем.
Таким образом, настройка правильной отправки уведомлений не только повышает уровень контроля над процессами, но и обеспечивает оперативное реагирование на потенциальные проблемы.