2010-03-02 40 views
7

這是一個用於bash-fu嚮導。不,實際上,我只是在開玩笑,你們大概都會知道這一點,除了我..Bash腳本,檢查錯誤,日誌記錄

我想創建一個備份shell腳本。這個想法很簡單:找到某個文件夾中的文件,超過7天,tar/gzip到另一個目錄,然後刪除它們。問題是,我不確定我是否有足夠的權限在目標目錄中創建tar/gzip文件。是否有任何(正確的)方法檢查文件是否已成功創建,如果有,請刪除文件。否則,請跳過該部分並且不要銷燬客戶的數據。我聽說他們不太喜歡那個。

這是我到目前爲止有:

01: #!/bin/bash 
02: 
03: ROOTDIR="/data/www" 
04: 
05: TAR="${ROOTDIR}/log/svg_out_xml/export_out_ack_$(date +%Y-%m-%d).tar" 
06: cd ${ROOTDIR}/exchange/export/out_ack/ 
07: find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" 
08: gzip ${TAR} 
09: find . -mtime +7 -type f -print0 | xargs -0 rm -f 

基本上,我需要檢查,如果一切順利上線7,8罰款,如果是執行9

此外,我d喜歡做這些操作的日誌文件,所以我知道一切都很好(這是一個夜間cron工作)。

+1

在這裏,所有的評論,使用一些事先安全。 – Recursion 2010-03-02 10:05:38

+0

從經驗說起,遞歸? :) – 2010-03-02 13:33:16

+0

你的標籤上寫着「bash」,但你的標籤上寫着「sh」。 – 2010-03-02 13:54:57

回答

6

進行日誌記錄,你可以用你的腳本片段在大括號和標準輸出重定向到一個日誌文件:

{ 
    script_command_1 
    script_command_2 
    script_command_3 
} >> /path/to/log_file 
+0

Kewl,我希望它能起作用,如果我這樣寫:'>> >> {{LOG} 2>&1' – 2010-03-02 14:50:11

+0

@dr:是的,它會的。 – 2010-03-02 15:04:15

5

討巧,但沒有明確的錯誤消息添加-e的家當,即#!/bin/sh -e這將導致如果一個命令失敗,shell退出..

的Cron應該給你通過郵件的錯誤信息我想是的。

如果你想全力支持後備計劃,我建議你使用已經完成的東西。那裏有一堆,大部分工作得很好。

+0

優秀的建議。我總是在我的腳本中使用'-e'。 – 2010-03-02 10:09:57

+0

感謝您的提示,非常有用!不幸的是,cron不會給我們任何東西,因爲我們不是這個系統的管理員。這將是很好,但.. – 2010-03-02 13:31:24

+0

@dr:它會如果你定義在您的crontab的MAILTO。 – falstro 2010-03-02 14:48:59

3

GNU tar具有--remove-files,它們將在文件添加到存檔後刪除文件。 v將導致它列出文件,因爲它添加它們。 z將通過gzip即時管道焦油。

您的find解決方案很活潑;一個文件可能符合調用之間的條件,因此被刪除但不備份。

+0

感謝您的回答。文件在調用之間非常不適合,因爲此腳本將在凌晨4點運行,因爲在我備份的文件夾中不應創建任何文件。當然,總是有一個用戶.. – 2010-03-02 13:28:30

11

進行日誌記錄,可以安排寫在標準輸出和/或標準的所有輸出錯誤去到一個文件。這樣一來,你就不需要重定向每個命令的輸出:

# Save standard output and standard error 
exec 3>&1 4>&2 
# Redirect standard output to a log file 
exec 1>/tmp/stdout.log 
# Redirect standard error to a log file 
exec 2>/tmp/stderr.log 

# Now the output of all commands goes to the log files 
echo "This goes to /tmp/stdout.log" 
echo "This goes to /tmp/stderr.log" 1>&2 
... 

# Print a message to the original standard output (e.g. terminal) 
echo "This goes to the original stdout" 1>&3 

# Restore original stdout/stderr 
exec 1>&3 2>&4 
# Close the unused descriptors 
exec 3>&- 4>&- 

# Now the output of all commands goes to the original standard output & error 
... 

只有當先前的一個成功執行命令,你可以用條件來把它們連:

# Execute command2 only if command1 succeeds, and command3 only if both succeed: 
command1 && command2 && command3 

# Execute command2 only if command1 fails 
command1 || command2 

所以你可以做這樣的事情

{ find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" && 
    gzip ${TAR} && 
    find . -mtime +7 -type f -print0 | xargs -0 rm -f } || 
    { echo "Something failed" 1>&2; exit 1 } 

或提供詳細的日誌輸出:

find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" || 
    { echo "find failed!!" 1>&2; exit 1 } 
gzip ${TAR} || 
    { echo "gzip failed!!" 1>&2; exit 1 } 
find . -mtime +7 -type f -print0 | xargs -0 rm -f || 
    { echo "cleanup failed!!" 1>&2; exit 1} 
+0

+1,非常棒的信息! – 2010-03-02 17:12:23

+0

'1>'隱含在'>' – 2010-03-02 17:39:32

+3

中,但是1>更清楚。 – Idelic 2010-03-02 17:59:56