所以我写了一个简短的脚本,我打算每天通过cron工作来打包我的站点文件并将它们发送到远程位置。 我也打算把数据库转储,但我还没有得到那么多。
然而,我今天的问题是,我不确定如何logging每个命令的输出,以查看命令可能输出的错误,警告或其他相关信息。 我也想安装一些失败的安全types,所以如果有什么可怕的错误脚本将停止死亡的轨道,并通过电子邮件或通知我。 好吧,电子邮件的事情并不重要,但会很好。
有人有任何想法吗? 这是我迄今为止。
顺便说一下,这两台服务器都是运行标准LAMP的CentOS 6.2。
#!/bin/sh ################################# ### Set Vars ################################# THEDATE=`date +%m%d%y%H%M` ################################# ### Create Archives ################################# tar -cf /root/backups/files/server_BAK_${THEDATE}.tar -C / var/www/vhosts gzip /root/backups/files/server_BAK_${THEDATE}.tar ################################# ### Send Data to Remote Server ################################# scp /root/backups/files/server_BAK_${THEDATE}.tar.gz user@host:/home/bak1/ftp/backups/ ################################# ### Remove Data from this Server ################################# rm -rf /root/backups/files/server_BAK_${THEDATE}.tar.gz
有点混乱的答案,但请仔细阅读。
当出现任何types的错误时,让脚本停在脚下:
set -e
这将确保如果你的任何命令失败,脚本将会在那里失败。 其他好主意:
function error_handler() { # This will get run when an error is detected } trap error_handler ERR
这将在命令失败时运行error_handler 。 每次脚本退出时,还可以使用EXIT处理程序来运行代码。
要捕获脚本的所有输出到一个文件:
exec &> some_log_file
也可以看到您的脚本在日志文件中执行的命令(非常适用于故障排除):
set -x
为了让你的脚本引发关于未定义variables的警告:
set -u
总结一下,开始你的脚本:
trap error_handler ERR exec &> some_log_file set -eux
如果你正在从cron运行脚本,如果你的脚本有任何输出,它会向你发送一封电子邮件。 为了在出现问题时只收到电子邮件, cat some_log_file在error handling程序中放置一个cat some_log_file ,然后进行设置。
更新 :回答你的其他问题。
if语句中运行该命令。 就像if ! <some command>; then <what do you do if it fails, or possibly nothing>; fi if ! <some command>; then <what do you do if it fails, or possibly nothing>; fi trap error_handler你还需要定义一个function error_handler 。 set -eu和set -eux不是一个坏主意,但是… …如果你担心安全,你不应该把mysql的密码放在命令行(任何运行pgrep -lf mysql都会看到它)。 改用选项文件。 然后你不需要担心日志文件中的密码。
option_file=`mktemp` cat > $option_file <<EOF [client] password = $DB_PASSWD user = $DB_USER EOF
然后用--default-extra-path=$option_file运行mysqldump 。 不要忘了在不再需要的时候删除$option_file 。
rsync而不是scp 。 它复制相对较大的文件效果更好。 您可以将每个命令的错误redirect到特定的文件。
grep da * 2> grep-errors.txt
这将错误从grepredirect到文件grep-errors.txt。
grep da * 1>&2
这会导致程序的标准输出被写入到stdout的文件描述符中。
rm -rf * 2>&1这会导致程序的stderr输出被写入相同的filedescriptor而不是stdout
rm -f $(find / -name core) &> /dev/null
这将把程序的每个输出放到一个文件中。 如果你想让命令通过绝对的沉默,这有时适合cron条目。 当然,你可以用一些文件replace/ dev / null,并把所有的输出写入它。
这是logging错误。 我知道这是简单的备份脚本,但你正在试图重新发明轮子。 在我看来,你应该检查Bacula。 这是一个非常大的解决scheme,只备份一台服务器,但它会做你所要求的所有问题。 Buckup,通知等等等等。 您将拥有最好的备份解决scheme之一。 只为一台或几台服务器设置它非常简单,你可以在几个小时内完成。
如果你仍然想使用你的脚本,那么你应该将所有的错误redirect到标准输出后,添加此脚本到Cron它会通过电子邮件发送该脚本的每个输出。 您应该只检查根/ etc /别名根目录,并写下你的邮件像这样:
root: [email protected]
我对脚本进行了一些更新。 这是新的。 尽pipe如此,
编辑:所以我做了更多的调整脚本来合并数据库的迭代备份。 以下是最新的版本。 我现在正在testing它的过程。
我的新问题是这样的:我不想在日志文件中显示数据库的密码,所以我将第一个“set”设置为“set -eu”。 但是我决定看看日志文件里脚本里面运行着什么命令,所以在数据库迭代和转储完成之后,我把“set”重置为“set -eux”。 我做了这个好习惯吗? 另外,如何在日志文件上显示时间戳?
#/bin/sh ################################# ### Set Vars ################################# LOCALBAKTMP='/root/backups/files' ###~~~PLACE WHERE TMP FILES GO LOCALBAKLOC='var/www/vhosts' ###~~~DIRECTORY TO BACKUP (NO SLASH IN FRONT) REMOTEUSR='user' ###~~~USER AT REMOTE SERVER REMOTEHOST='host' ###~~~REMOTE HOST ADDRESS REMOTEDEST='/home/bak1/ftp/backups/' ###~~~FILE DESTINATION AT REMOTE LOGDIR='/root/backups/logs/' ###~~~LOCAL BACKUP LOG DIRECTORY DELLOGSDAYS='30' ###~~~DAYS TO STORE LOG FILES THEDATE=`date +%m%d%y%H%M` ###~~~DATE VARIABLE DB_BACKUP="/root/backups/files/dbs" ###~~~DB BACKUP LOCATION LOCALDBLOC="root/backups/files/dbs" ###~~~DB FILES TO BAK DB_USER="dbuser" ###~~~DB ROOT USER DB_PASSWD="dbpassword" ###~~~DB ROOT PASS HN=`hostname | awk -F. '{print $1}'` ###~~~DO NOT CHANGE ################################# ### Set Logging ################################# trap error_handler ERR exec &> ${LOGDIR}bak_${THEDATE}.log set -eu ################################# ### Dump MySQL ################################# for db in $(mysql --user=$DB_USER --password=$DB_PASSWD -e 'show databases' -s --skip-column-names|grep -vi information_schema); do mysqldump --user=$DB_USER --password=$DB_PASSWD --opt $db | gzip > "$DB_BACKUP/mysqldump-$HN-$db-$(date +%Y-%m-%d).sql.gz"; done #Log commands for the rest of the script set -eux ################################# ### Create Archives ################################# tar -cf ${LOCALBAKTMP}/server_BAK_${THEDATE}.tar -C / ${LOCALBAKLOC} gzip ${LOCALBAKTMP}/server_BAK_${THEDATE}.tar tar -cf ${LOCALBAKTMP}/db_BAK_${THEDATE}.tar -C / ${LOCALDBLOC} gzip ${LOCALBAKTMP}/db_BAK_${THEDATE}.tar tar -cfz full_BAK_${THEDATE}.tar.gz *_BAK_${THEDATE}.tar.gz ################################# ### Send Data to Remote Server ################################# scp ${LOCALBAKTMP}/full_BAK_${THEDATE}.tar.gz ${REMOTEUSR}@${REMOTEHOST}:${REMOTEDEST} ################################# ### Remove Data from this Server ################################# rm -f ${LOCALBAKTMP}/*_BAK_${THEDATE}.tar.gz rm -rf ${DB_BACKUP}/*.sql.gz find ${LOGDIR}* -mtime +${DELLOGSDAYS} -exec rm {} \;