Linux 使用 tar 打包压缩多个文件夹(支持过滤)

在 Linux 系统中使用 tar 打包压缩多个文件夹

支持自定义排除文件类型(针对所有指定的文件夹)
支持排除某个文件夹中的某些子目录

定义变量

EXCFILE 定义排除的文件类型 .log .sock (多值空格隔开)

1
2
# 排除所有的 .log .sock 文件
EXCFILE=".log .sock"

BACKUP_LIST 指定要备份的文件夹(key=value, value为文件夹排除列表[多个值必须以空格分隔])

1
2
3
4
5
declare -A BACKUP_LIST
# 排除 /opt 目录下的 log .cache .vim 文件夹
BACKUP_LIST["/opt"]="log .cache .vim"
# 排除 /var 目录下的 log 文件夹
BACKUP_LIST["/var"]="log"

BACKUP_TO 指定压缩文件存放的路径
FileTGZ 文件命名格式

1
2
3
4
BACKUP_TO=/BackupData
DATE=$(date "+%Y%m%d_%H%M%S")
FileType=.tar.gz
FileTGZ=${BACKUP_TO}/Data-${DATE}${FileType}

SAVE_COUNT 指定存放最大数, 超过此数量会自动删除过早的文件 (可搭配 cronteb 使用)

1
SAVE_COUNT=7

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/bash
# author: ali
# email: solitude@hraulein.com
# create: 2023/12/04
# note: Linux 使用 tar 打包压缩多个文件夹(支持过滤)

EXCFILE=".log .sock"
declare -A BACKUP_LIST
BACKUP_LIST["/opt"]="log .cache .vim"
BACKUP_LIST["/var"]="log"

BACKUP_TO=/BackupData
DATE=$(date "+%Y%m%d_%H%M%S")
FileType=.tar.gz
FileTGZ=${BACKUP_TO}/Data-${DATE}${FileType}
SAVE_COUNT=7

function workdir (){
if [ ! -d "$1" ]; then mkdir -p "$1"; fi
}

function backup (){
for dir in ${!BACKUP_LIST[*]}
do
_dirlist+=${dir}" "
for exc in ${BACKUP_LIST[${dir}]}; do _exclist+="--exclude=${dir}/${exc} "; done
done
for file in ${EXCFILE}; do _exclist+="--exclude=*${file} "; done
echo "$(date) 正在备份数据, 请等待..."
echo "$(date) tar -zcPf ${FileTGZ} ${_exclist} ${_dirlist}"
sudo tar -zcPf ${FileTGZ} ${_exclist} ${_dirlist}
if [ $? -eq 0 ]; then
echo "$(date) 备份成功: ${FileTGZ}"
else
echo "$(date) 备份失败, 原因未知"
fi
}

function delete (){
echo "$(date) 历史备份数据删除前检查..."
sleep 2
count=$(find $1 -name "Data-*${FileType}" |sort |wc -l)
if [ $count -gt $2 ]; then
dellist=$(find $1 -name "Data-*${FileType}" |sort |head -n $(expr ${count} - $2))
for tgz in ${dellist}; do rm -f $tgz; done
echo "$(date) 删除文件: $dellist "
else
echo "$(date) 未满足删除条件"
fi
}

function main (){
workdir ${BACKUP_TO}
backup
delete ${BACKUP_TO} ${SAVE_COUNT}
}

main