2009-08-20 78 views
4

我有一个cron作业:Cron作业stderr电子邮件和日志文件?

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

哪里SP_s是脚本的路径和LP_s是日志文件的路径。这将stdout发送到我的电子邮件的日志文件和stderr。

我如何?:
1)标准输出和标准错误发送到日志文件,
2)和标准错误发送到电子邮件

,或者换一种说法:标准错误输出到日志文件和电子邮件都,并且只对日志文件标准输出。

更新: 我到目前为止所得到的答案都不符合我制定的标准或似乎适合CRON工作的标准。

我看到了这个,它旨在“将STDOUT和STDERR从一个命令发送到一个文件,然后将STDERR发送到另一个文件”(由unix.com上的zazzybob发布),这看起来接近我想要的这样做,我不知道是否会激发别人比我更聪明:

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

我想cron来STDERR发送电子邮件,而不是“其他文件”。

回答

0

我的经验(ubuntu)是'crontab'只发送邮件'stderr'(我有输出指向一个日志文件,然后存档)。这很有用,但我希望确认脚本能够运行(即使没有错误发送到stderr),以及一些有关需要多长时间的细节,我发现它是发现潜在问题的好方法。

我发现我可以最轻松地绕着这个问题绕过这个问题的方式是写脚本与一些重复的'回声在里面。广泛的常规'回声结束于日志文件。对于我想在我的crontab'MAILTO'电子邮件中发现的重要的非错误位,我使用了'echo',它指向'1> & 2'的stderr。

因此这样的:

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,并且只有''2'转回到电子邮件; stdout转到日志)'的回显行,但我发现这比我最初想象的解决方案要好,因为电子邮件发现我并且我不必去在日志文件中寻找问题。

-1

我假设你正在使用bash,您重定向输出和错误,像这样

1> LOG_FILE 
2> LOG_FILE 

发送包含标准错误的身体像这样

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

我不知道邮件如果你只能在一个段落中做到这一点,因为这

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

如果你可以做有stdout/err在单独的文件,这应该这样做:

($SP_s/StartDailyS1.sh 2>&1 >$LP_s/MirrorLogS1.txt.stdout) | tee $LP_s/MirrorLogS1.txt.stderr 
+0

谢谢“号”, 我看到这种情况,其目的是“从发送的命令输出和错误到一个文件,然后只需STDERR到另一个文件”,发表zazzybob上unix.com: ( (my_command 3>&1 1>&2 2>&3)| tee error_only.log)> all.log 2>&1 它与您的建议和我想要做的非常相似(除了我希望cron发送STDERR电子邮件而不是“另一个文件”)。不幸的是我没有足够的知识来修改它以满足我的需求。它能激发任何想法吗? 干杯, Steph – 2009-08-24 19:22:44

+0

上面发送stdout和stderr到一个文件,并且还发送stderr到stdout(所以它会被邮寄如果你从一个cron作业运行)。所以stderr会收到你的邮件(我不知道如何发送stdout/err到只有一个文件,而不是上面的2),并且仍然只发送stderr到邮件) – nos 2009-08-24 20:15:01

0

有点棘手,如果你想标准输出标准错误组合在一个文件中,标准错误尚未tee'd到它自己的流。

这应该这样做(错误检查,清理和广义鲁棒性略):

#! /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)其中它被附加到日志文件(其中也附加了你的命令的标准输出)并且回到常规stderr

3

由于我只是在看tee的信息页面(试图弄清楚如何做同样的事情),我可以为你回答最后一点。

这是大多数有方式,即用 “>(email_command)”

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

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

但替换 “error_only.log”:根据发球的文档,这将工作中bash,但不在/ bin/sh中。如果你把它放在一个cron脚本中(就像在/etc/cron.daily/中一样),那么你可以在顶部使用#!/ bin/bash。但是,如果你把它作为一个单线程在一个crontab中,那么你可能需要用bash包装它。“”

+0

这是一个很好的解决方案。我看到的唯一缺陷是每次都覆盖日志文件。应该使用'>> all.log'来追加。 – wyattisimo 2014-03-12 16:11:40

3

不知道为什么没有人提到这一点。

如果您在用户crontab中指定MAILTO = STDOUT已通过邮件发送,则使用CRON。

[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 
-1

你可以尝试写另一个的cronjob读取日志文件和“显示”日志(实际上只是让cron的电子邮件发送给您)

1

除非我失去了一些东西:

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

2> & 1重定向标准错误到stdout

>>重定向命令标准输出到日志文件

|三通重复stderr的(从2> & 1)至日志文件,然后使其通过到stdout由cron邮寄给MAILTO

我与

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

这的确示出了世界在控制台测试了它和内两种文本x

丑陋的东西是重复的文件名。 stdout/stderr中的不同缓冲可能会使file.log中的文本有点混乱。

相关问题