tar -g 可以实现增量备份,但是如果第一次到第二次备份之间时删除了一些文件,那解压恢复时就会有问题。被删除了的文件还会存在。
于是我写了一些脚本用于管理和恢复时删除这些不该存在的文件。
目录结构
├── backup
│ ├── backup@2021-07-30_16-08-43.tar.gz
│ ├── backup@2021-08-03_12-50-23.tar.gz
│ ├── .backup-snapshot
│ ├── .date
│ ├── e2021-07-30_16-08-43
│ ├── e2021-08-03_12-50-23
│ ├── f2021-07-30_16-08-43
│ └── f2021-08-03_12-50-23
├── backup.sh
├── error.log
├── index.sh
├── init.sh
└── restoring.sh
- .backup-snapshot 文件是tar -g 命令生成的快照文件
- .date 是存储备份日期的文件
- f2021-07-30_16-08-43 存的是文件清单
- e2021-07-30_16-08-43 存的是空文件夹清单
- error.log 是日志文件
脚本
index.sh 主脚本
#!/bin/bash
# 脚本绝对路径
export workdir=$(dirname $(readlink -f "$0"))
# 备份路径
export path='/'
# 备份文件存储路径
export backup_path=$workdir'/backup'
#快照文件
export snapshot=$backup_path"/.backup-snapshot"
export exclude="\
--exclude=/proc \
--exclude=/tmp \
--exclude=/mnt \
--exclude=/dev \
--exclude=/sys \
--exclude=/run \
--exclude=/media \
--exclude=/var/log \
--exclude=/var/cache/apt/archives \
--exclude=/usr/src/linux-headers* \
--exclude=/home/*/.gvfs \
--exclude=/home/*/.cache \
--exclude=/home/*/.local/share/Trash"
while getopts "br:il" opt; do
case $opt in
b)
./backup.sh $path 2>./error.log
;;
r)
./restoring.sh $OPTARG
;;
l)
i=1
cat $backup_path"/.date" | while read d; do
echo $i" -> "$d
i=$((i + 1))
done
;;
i)
./init.sh
;;
?) ;;
esac
done
init.sh 初始化脚本
#!/bin/bash
read -p "真的要清空[Y?]" a
if [ "$a" = "Y" ];then
sudo rm -r $backup_path
mkdir $backup_path
echo -n '' > $backup_path"/.date"
echo "已清空"
else
echo "bye~"
fi
backup.sh 备份脚本
#!/bin/bash
echo $path
#时间
d=$(date +%Y-%m-%d)_$(date +%H-%M-%S)
#压缩包名称
file=$backup_path"/backup@"$d".tar.gz"
f=$backup_path"/f"$d
e=$backup_path"/e"$d
#排除路径
p=$exclude" --exclude="$workdir
cd /
sudo tar -g $snapshot -cvpzf $file $p $path
# 日期
echo "$d" >> $backup_path"/.date"
gp='^'$workdir'.*\|^/proc\|^/tmp\|^/mnt\|^/dev\|^/sys\|^/run\|^/media\|^/var/log\|^/var/cache/apt/archives\|^/usr/src/linux-headers.*\|^/home/.*/.gvfs\|^/home/.*/.cache$\|^/home/.*/.local/share/Trash'
# 文件清单
sudo find $path -type f | grep -v $gp > $f
# 空文件夹清单
sudo find $path -type d -empty | grep -v $gp > $e
restoring.sh 恢复脚本
#!/bin/bash
# 序号
n=$1
# 要恢复到的时间
a=$(cat $backup_path"/.date" | sed -n $n'p')
echo $a
file1=$backup_path'/f'$a
file2=$workdir"/.t.tmp"
file=$workdir"/.tmp"
keep=$(cat $file1)
if [ -n "$keep" ]; then
echo $file2 > $file2
echo $file >> $file2
echo "========="
cd /
cat $backup_path"/.date" | awk 'NR<'$n > $file
while read d
do
cat $backup_path"/f"$d >> $file2
sudo tar -xvpzf $backup_path"/backup@"$d".tar.gz" -C / --numeric-owner
done < $file
sudo tar -xvpzf $backup_path"/backup@"$a".tar.gz" -C / --numeric-owner
echo "========="
# 文件差集
sort $file2 $file1 $file1 | uniq -u | sudo xargs rm -vr
fi
find $path -type d -empty -delete
keep=$(cat $backup_path'/e'$a)
if [ -n "$keep" ]; then
sudo mkdir -p $keep
f
用法
# 备份
./index.sh -b
# 恢复到第二个日期 即2021-08-03_12-50-23
./index.sh -r 2
# 查看备份日期
./index.sh -l
# 1 -> 2021-07-30_16-08-43
# 2 -> 2021-08-03_12-50-23
# 初始化或清空备份
./index.sh -i
# 真的要清空[Y?]n
# bye~
缺陷
- 备份时如果改变了要备份的文件会备份失败
- 空文件夹的权限可能会改变。