Cron задание stderr на электронную почту И файл журнала? - PullRequest
4 голосов
/ 21 августа 2009

У меня есть работа cron:

$SP_s/StartDailyS1.sh >$LP_s/MirrorLogS1.txt

Где SP_s - это путь к сценарию, а LP_s - это путь к файлу журнала. Это отправляет stdout в файл журнала и stderr на мою электронную почту.

Как мне?:
1) отправить оба stdout И stderr в лог-файл,
2) И отправьте stderr на электронную почту

или, другими словами: stderr для файла журнала и электронной почты, а stdout только для файла журнала.

UPDATE: Ни один из ответов, которые я получил до сих пор, не соответствует установленным мною критериям или не подходит для работы в CRON.

Я видел это, предназначенное для «отправки STDOUT и STDERR из команды в один файл, а затем просто STDERR в другой файл» (опубликовано zazzybob на unix.com), что похоже на то, что я хочу и мне было интересно, вдохновит ли это кого-нибудь более умного, чем я:

(( my_command 3>&1 1>&2 2>&3 ) | tee error_only.log ) > all.log 2>&1 

Я хочу, чтобы cron отправлял STDERR по электронной почте, а не «другому файлу».

Ответы [ 9 ]

3 голосов
/ 20 января 2010

Не знаю, почему никто не упомянул это.

С CRON, если вы указали MAILTO = в пользовательском crontab, STDOUT уже отправлено по почте.

Пример

[temp]$ sudo crontab -u user1 -l
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=user1
# transfer order shipping file every 3 minutes past the quarter hour
3,19,33,48 * * * * /home/user1/.bin/trans.sh
3 голосов
/ 29 ноября 2009

Поскольку я просто просматривал информационную страницу для Ти (пытаясь понять, как сделать то же самое), я могу ответить на последний вопрос для вас.

Это большая часть пути туда:

(( my_command 3>&1 1>&2 2>&3 ) | tee error_only.log ) > all.log 2>&1

но замените "error_only.log" на "> (email_command)"

(( my_command 3>&1 1>&2 2>&3 ) | tee >(/bin/mail -s "SUBJECT" "EMAIL") ) > all.log 2>&1

Примечание: в соответствии с документами Ти это будет работать в bash, но не в / bin / sh. Если вы помещаете это в скрипт cron (как в /etc/cron.daily/), тогда вы можете просто #! / Bin / bash сверху. Однако, если вы помещаете это как однострочник в crontab, вам, возможно, придется обернуть его в bash -c ""

2 голосов
/ 21 августа 2009

Если вы можете использовать stdout / err в отдельных файлах, это должно сделать:

($SP_s/StartDailyS1.sh 2>&1 >$LP_s/MirrorLogS1.txt.stdout) | tee $LP_s/MirrorLogS1.txt.stderr
1 голос
/ 23 января 2012

Если я что-то упустил:

command 2>&1 >> file.log | tee -a file.log

2> & 1 перенаправляет stderr на стандартный вывод

>> перенаправляет обычную команду stdout в файл журнала

| Т.е. дублирует stderr (из 2> & 1) в лог-файл и передает его в stdout, который cron отправляет по почте в MAILTO

Я проверил это с

(echo Hello & echo 1>&2 World) 2>&1 >> x | tee -a x

Что действительно показывает Мир в консоли и оба текста внутри x

Ужасная вещь - это повторяющееся имя файла. И другая буферизация из stdout / stderr может сделать текст в file.log немного грязным, я думаю.

0 голосов
/ 09 апреля 2018

Я думаю, что решение будет:

$SP_s/StartDailyS1.sh 2>&1 >> $LP_s/MirrorLogS1.txt | tee -a $LP_s/MirrorLogS1.txt

Это будет:

  • добавить стандартный вывод к $LP_s/MirrorLogS1.txt
  • добавить стандартную ошибку к $LP_s/MirrorLogS1.txt
  • печатает стандартную ошибку, поэтому cron отправит письмо в случае ошибки
0 голосов
/ 14 апреля 2017

Мой опыт (ubuntu) заключается в том, что crontab отправляет только письма stderr (у меня есть выходные данные, направленные в файл журнала, который затем архивируется). Это полезно, но я хотел получить подтверждение того, что скрипт был запущен (даже если нет ошибок для 'stderr'), и некоторые подробности о том, сколько времени это заняло, и я считаю, это хороший способ обнаружить потенциальные проблемы.

Я нашел способ, которым мне легче всего обойти эту проблему, было написать сценарий с некоторыми дублирующими эхо. Обширное регулярное эхо заканчивается в файле журнала. Для важных битов, не связанных с ошибками, которые я хочу в своем электронном письме crontab 'MAILTO', я использовал 'echo', который направлен на stderr с '1> & 2'.

Таким образом, это:

    Frmt_s="+>>%y%m%d %H%M%S($HOSTNAME): " # =Format of timestamp: "<YYMMDD HHMMSS>(<machine name>): "
    echo `date "$Frmt_s"`"'$0' started." # '$0' is path & filename
    echo `date "$Frmt_s"`"'$0' started."  1>&2 # message to stderr

# REPORT:
    echo ""
    echo "================================================"
    echo "================================================" 1>&2 # message to stderr
    TotalMins_i=$(( TotalSecs_i / 60 )) # calculate elapsed mins
    RemainderSecs_i=$(( TotalSecs_i-(TotalMins_i*60) ))
    Title_s="TOTAL run time"
    Summary_s=$Summary_s$'\n'$(printf "%-20s%3s:%02d" "$Title_s" $TotalMins_i $RemainderSecs_i)
    echo "$Summary_s"
    echo "$Summary_s" 1>&2 # message to stderr
    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" 1>&2 # message to stderr
    echo ""
    echo `date "$Frmt_s"`"TotalSecs_i: $TotalSecs_i"
    echo `date "$Frmt_s"`"'$0' concluded." # '$0' is path & filename
    echo `date "$Frmt_s"`"'$0' concluded."  1>&2 # message to stderr

Посылает мне электронное письмо, содержащее это (при отсутствии ошибок строки, начинающиеся с 'ssh:' и 'rsync:' не появляются):

170408 030001(sb03): '/mnt/data1/LoSR/backup_losr_to_elwd.sh' started.
ssh: connect to host 000.000.000.000 port 0000: Connection timed out
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(226) [Receiver=3.1.0]
ssh: connect to host 000.000.000.000 port 0000: Connection timed out
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(226) [Receiver=3.1.0]
================================================
S6 SUMMARY (mins:secs):
'Templates'           2:07
'Clients'             2:08
'Backups'             0:10
'Homes'               0:02
'NetAppsS6'          10:19
'TemplatesNew'        0:01
'S6Www'               0:02
'Aabak'               4:44
'Aaldf'               0:01
'ateam.ldf'           0:01
'Aa50Ini'             0:02
'Aadmin50Ini'         0:01
'GenerateTemplates'   0:01
'BackupScripts'       0:01
TOTAL run time       19:40
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170408 031941(sb03): '/mnt/data1/LoSR/backup_losr_to_elwd.sh' concluded.

Это не удовлетворяет моему первоначальному желанию "отправить как stdout, так и stderr в лог-файл" (stderr, и только 'echo'ed строки с' 1> & 2 'идут на электронную почту; stdout идет в журнал) , но я считаю, что это лучше, чем мое первоначальное решение, так как электронная почта находит меня, и мне не нужно искать проблемы в файле журнала.

0 голосов
/ 11 апреля 2011

Вы можете попробовать написать еще один cronjob, чтобы прочитать файл журнала и «отобразить» журнал (на самом деле, просто позвольте ему отправить его вам по электронной почте)

0 голосов
/ 21 августа 2009

Немного сложно, если вы хотите, чтобы stdout и stderr были объединены в один файл, с stderr , но при этом они были объединены в отдельный поток.

Это должно быть сделано (проверка ошибок, очистка и общая устойчивость исключены):

#! /bin/sh

CMD=..../StartDailyS1.sh
LOGFILE=..../MirrorLogS1.txt
FIFO=/tmp/fifo

>$LOGFILE

mkfifo $FIFO 2>/dev/null || :

tee < $FIFO -a $LOGFILE >&2 &

$CMD 2>$FIFO >>$LOGFILE

stderr отправляется в именованный канал, выбирается tee(1), где он добавляется в лог-файл (в который также добавляется stdout вашей команды ) и возвращается назад к обычному stderr .

0 голосов
/ 21 августа 2009

Я предполагаю, что вы используете bash, вы перенаправляете stdout и stderr, как это так

1> LOG_FILE
2> LOG_FILE

чтобы отправить письмо, содержащее stderr в теле, что-то вроде этого

2> MESSAGE_FILE
/bin/mail -s "SUBJECT" "EMAIL_ADDRESS" < MESSAGE_FILE

Я не уверен, что вы можете сделать это только в одном отрывке, как это

/bin/mail -s "SUBJECT" "EMAIL_ADDRESS" <2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...