![如何在 bash 脚本上使用 md5sum 测试进行循环?](https://linux22.com/image/109922/%E5%A6%82%E4%BD%95%E5%9C%A8%20bash%20%E8%84%9A%E6%9C%AC%E4%B8%8A%E4%BD%BF%E7%94%A8%20md5sum%20%E6%B5%8B%E8%AF%95%E8%BF%9B%E8%A1%8C%E5%BE%AA%E7%8E%AF%EF%BC%9F.png)
我有这个脚本,它创建数据库的 mysql 转储并将其发送到存储服务器。但我发现,有时生成的文件大小错误,即使使用 rsync 发送文件也是如此。
我想测试远程文件的 md5sum,如果哈希值相同,则删除本地文件。但是,如果哈希值不同,则会重新尝试 rsync。
原来的脚本是:
#!/bin/bash
# database credentials
DATABASEHOST=<host>
DATABASEUSER=<user>
DATABASEPASSWORD=<password>
DATABASESCHEMA=<schema>
DATABASEENV=<env>
# Local directory of mysqldump file
LOCALDIR=<localdir>
# Temporary directory for compressed file
TEMPDIR=<tempdir>
# Remote Directory for backups.
REMOTEDIR=<remote-dir>
# USERname to login as
BACKUPUSER=<backupuser>
# Backup host to login to
BACKUPHOST=<backuphost>
# mysqldump file
MYSQLDUMPFILE="$(date +%Y%m%d)"_bkp_"$DATABASESCHEMA".sql
# compressed file
COMPRESSEDFILE="$(date +%Y%m%d)"_"$DATABASEENV"_"$DATABASESCHEMA".tar.gz
#--- end config
echo $(date +%H:%M)
echo "Creating the MySQL dump"
mysqldump --host="$DATABASEHOST" --user="$DATABASEUSER" --password="$DATABASEPASSWORD" --single-transaction "$DATABASESCHEMA" > "$LOCALDIR"/"$MYSQLDUMPFILE"
#echo "Generating md5sum"
md5sum "$LOCALDIR"/* > "$LOCALDIR"/checklist.chk
#echo "Compressing the dump and checklist"
tar -cvzf "$TEMPDIR"/$(date +%Y%m%d)"_"$DATABASEENV"_"$DATABASESCHEMA".tar.gz" "$LOCALDIR"/*
#echo "Sending the compressed file to storage location"
rsync -azvh "$TEMPDIR"/"$COMPRESSEDFILE" "$BACKUPHOST":"$REMOTEDIR"
echo "Removing generated files"
rm "$LOCALDIR"/checklist.chk > /dev/null 2>&1
rm "$LOCALDIR"/"$MYSQLDUMPFILE" > /dev/null 2>&1
rm "$TEMPDIR"/"$COMPRESSEDFILE" > /dev/null 2>&1
echo $(date +%H:%M)
答案1
- rsync 知道文件何时不完整。只需定期运行 rsync,它就会根据需要自行重新发送文件的新部分。
- 有可能 $TEMPDIR 太小而无法包含 tar czvf 吗?那么你会用 rsync 发送那个(不完整的)文件吗?
为什么不简化:
- 像你一样转储数据库
- 然后
cd "$LOCALDIR" && rsync -azvh *_bkp_*.sql "$BACKUPHOST":"$REMOTEDIR"
答案2
如果没有 rsync 指示错误或您的机器崩溃(因此 rsync 永远不会返回,因为机器死了),您所描述的内容永远不会发生。看我的评论对此的一些建议。
然而,计算和存储校验和是一种很好的做法,并且检查相当容易 — 只要您可以 ssh 到另一台计算机或在其上运行单独的脚本(假设所有文件名中都没有单引号):
# the cut below is to get the MD5 only, without the file name.
md5_local="$(md5sum "$REMOTEDIR/$COMPRESSEDFILE" | cut -d' ' -f1)"
md5_remote="$(ssh "$BACKUPHOST" "md5sum '$REMOTEDIR/$COMPRESSEDFILE'" | cut -d' ' -f1)"
if [ "$md5_local" = "" ]; then
echo "Something went terribly wrong."
elif [ "$md5_local" = "$md5_remote" ]; then
echo "MD5s match"
else
echo "MD5s DO NOT match"
fi
您可以做的另一件事(可能更可取)是将 MD5 文件添加到 rsync 中,并将其与备份一起存储。这可以让您确认备份没有损坏。
PS:你应该考虑一个真正的备份系统,至少如果你有多台机器的话。