2009-08-20 76 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中的文本有點混亂。

相關問題