设置远程备份脚本的日志记录

设置远程备份脚本的日志记录

因此我编写了一个简短的脚本,计划每天通过 cron 作业运行该脚本,以打包我的站点文件并将其发送到远程位置。我还计划合并数据库转储,但目前还没有做到这一点。

但是,我今天的问题是,我不确定如何记录每个命令的输出,以记录命令可能输出的错误、警告或其他相关信息。我还想安装某种故障保护装置,这样如果出现严重错误,脚本就会立即停止运行并通过电子邮件或其他方式通知我。好吧,电子邮件这件事并不那么重要,但会很好。

有人对此有什么想法吗?以下是我目前的想法。

顺便说一下,两台服务器都是运行标准 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

答案1

答案有点混乱,但请仔细阅读。

当出现任何类型的错误时让脚本立即停止运行:

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

要使脚本抛出有关未定义变量的警告:

set -u

总而言之,使用以下命令启动脚本:

trap error_handler ERR
exec &> some_log_file
set -eux

如果您从 cron 运行脚本,则当脚本有任何输出时,它会向您发送电子邮件。如果仅在出现问题时才收到电子邮件,请cat some_log_file在错误处理程序中输入一个,这样就完成了。

更新:回答您的其他问题。

  • 为了防止错误破坏整个脚本,您可以在语句中运行该命令if。例如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
    

    然后mysqldump使用运行。当你不再需要它时,--default-extra-path=$option_file不要忘记删除它。$option_file

  • 使用rsync而不是scp。 它对于复制相对较大的文件效果更好。

答案2

您可以将每个命令的错误重定向到特定的文件。

grep da * 2> grep-errors.txt

这会将错误从 grep 重定向到文件 grep-errors.txt。

grep da * 1>&2

这将导致程序的 stderr 输出被写入与 stdout 相同的文件描述符。

rm -rf * 2>&1 这将导致程序的 stderr 输出被写入与 stdout 相同的文件描述符

rm -f $(find / -name core) &> /dev/null

这会将程序的每个输出放置到一个文件中。如果您希望命令绝对安静地传递,这有时适用于 cron 条目。当然,您可以用某个文件替换 /dev/null 并将所有输出写入其中。

这是用于记录错误。我知道这是简单的备份脚本,但你又在重复做无用功。我认为你应该看看 Bacula。对于仅备份一台服务器来说,这是一个相当大的解决方案,但它可以满足你所有要求。备份、通知等等。你将拥有最好的备份解决方案之一。为一台或几台服务器设置它非常简单,你可以在几个小时内完成。

如果您仍想使用脚本,则应将所有错误重定向到 stdout。将此脚本添加到 cron 后,它会通过电子邮件向您发送该脚本的每个输出。您应该只检查 /etc/aliases 中的 root 条目,并在那里写邮件,如下所示:

root: [email protected]

答案3

我对剧本做了一些更新。这是新剧本。不过仍在努力,

编辑:因此,我对脚本进行了更多调整,以纳入数据库的迭代备份。以下是最新版本。我现在正在测试它。

我的新问题是:我不想在日志文件上显示数据库的密码,因此我将第一个“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 {} \;

相关内容