2010-03-02 91 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