重写了服务器备份shell脚本,并加入了main函数
大家好,我是无能。
我重写了之前写的一个用于创建备份的shell脚本。
前言
虽然是之前写的,但重新审视时,发现没有包含删除旧的tar.gz备份文件的代码,而且感觉会有点长,所以就将其整理到了main函数中。
对于我这种怕麻烦的人来说,尽可能地精简代码很重要,所以我重写了它。
实际上,如果能通过参数指定备份目的地和源,会更具通用性,并且在写入cron时也更容易理解,所以将来我会这样做。
代码解析
#!/bin/bash
MOUNT_DIR="/your/mount/point"
SRC_DIR="/want/to/backup/dir"
BK_DIR="backupdir"
EXCLUDE_FILE="" # 除外ファイル指定 --exclude=your/path
W_DIR=`echo $SRC_DIR | awk -F/ '{print $(NF)}'`
# マウントポイントを確認し、マウントされていなければマウントする
check_mount() {
df | grep "$MOUNT_DIR" > /dev/null
if [ $? -ne 0 ]; then
break
else
mount $MOUNT_DIR || exit 1
fi
}
# 古いバックアップファイルを削除する
rm_old_backups() {
BK_COUNT=`ls -1 $MOUNT_DIR/$BK_DIR/*.tar.gz 2>/dev/null | wc -l`
if [ "$BK_COUNT" -ge 3 ]; then
ls -1t $MOUNT_DIR/$BK_DIR/*.tar.gz | tail -n +4 | while read file; do
rm -f "$file"
done
fi
}
# バックアップを作成する
create_backup() {
rsync -av $EXCLUDE_FILE $SRC_DIR $MOUNT_DIR/$BK_DIR
tar cfz $MOUNT_DIR/$BK_DIR/"$W_DIR"_`date +"%Y%m%d"`.tar.gz -C $MOUNT_DIR/$BK_DIR $W_DIR
rm -rf $MOUNT_DIR/$BK_DIR/$W_DIR/*
}
main() {
check_mount # マウントを確認し、必要ならマウント
mkdir -p $MOUNT_DIR/$BK_DIR # バックアップディレクトリの作成
rm_old_backups # 古いバックアップの削除
create_backup # 新しいバックアップの作成
umount $MOUNT_DIR || exit 1 # マウント解除
}
main
由于假设会进行挂载/卸载操作,因此需要加入相应的判断。奇怪的是,虽然有mountpoint命令可以判断是否已挂载,但我尝试后发现即使已挂载也会显示“未挂载”,无法获取正确的返回值。
因此我突然想到,如果未挂载,它就不会出现在df的结果中。所以,如果我grep df的标准输出,并根据是否能grep到挂载点来判断返回值,应该会相当可靠吧……
最初,我只是简单地使用cp命令复制一次,然后用tar打包,但我想指定“复制时排除的文件”,而rsync似乎可以做到。原来大家都在用rsync啊。
特意指定$W_DIR的原因是rsync会用到它,所以需要提前创建这个值。
而关键在于删除旧tar.gz文件的判断逻辑。如果用ls来检查,就不必像find那样贪婪地深入到下层目录,我感觉这样对磁盘I/O的负载更小,也更安全,所以就尝试了这种方法。
通过tail获取文件名,可以明确决定允许保留多少个文件,我觉得这无意中是个不错的方法。
结束
说实话,我感觉也没必要非得放到main函数里,但结果是代码变得更易读了,所以就这么办吧。
那么,下次再见。