备份脚本

备份脚本

一、日常备份

如果你正在使用 Linux 系统处理一个重要的项目,那么可以创建一个 shell 脚本来自动备份特定目录。这有助于避免从主归档文件( main archive file )执行耗时的恢复过程。

1.1 基本功能拆解

在 Linux 世界中,备份数据的工作是由 tar 命令完成的。

  • 先来看一个使用 tar 命令来创建工作目录归档文件的例子:
# 1.列出待归档的文件。
[root@VM-8-11-centos tmp]# ls
a.txt  b.txt  c.txt  dir1  dir2  error.log  info.log  service.log  test.txt
[root@VM-8-11-centos tmp]# 

# 2.创建归档。
# 注意:(tar)命令会显示一条警告消息,指出它删除了路径开头的斜线。这意味着将路径从绝对路径改为了相对路径,以便将(tar)归档文件提取到文件系统中的任何位置。
[root@VM-8-11-centos tmp]# tar -cf archive.tar /home/tmp/*.*
tar: Removing leading `/' from member names
[root@VM-8-11-centos tmp]# 

# 3.列出创建完成的归档。
[root@VM-8-11-centos tmp]# ls archive.tar 
archive.tar
[root@VM-8-11-centos tmp]# 
  • 如果不想在脚本中输出警告消息,则可以将 STDERR 重定向到 /dev/null 文件:
# 1.创建归档时,重定向警告信息。
[root@VM-8-11-centos tmp]# tar -cf archive.tar /home/tmp/*.* 2>/dev/null 
[root@VM-8-11-centos tmp]# 

# 2.列出创建完成的归档。
[root@VM-8-11-centos tmp]# ls archive.tar 
archive.tar
[root@VM-8-11-centos tmp]# 
  • 由于 tar 归档文件会占用大量的磁盘空间,因此最好压缩一下。对此,我们可以使用 -z 选项。(会使用 gzip 压缩 tar 归档文件)
  • 另外,采用 .tar.gz 或 .tgz 表示是经过 gzip 压缩过的文件:
# 1.加入(-z)选项,并以(.tgz)命名创建压缩归档。
[root@VM-8-11-centos tmp]# tar -zcf archive.tgz /home/tmp/*.* 2>/dev/null
[root@VM-8-11-centos tmp]# 

# 2.经过压缩后的归档(.tgz后缀),字节数明显小于未压缩归档(.tar后缀)。
[root@VM-8-11-centos tmp]# ls -l archive.*
-rw-rw-r--+ 1 root root 10240 Jul 10 15:39 archive.tar
-rw-rw-r--+ 1 root root   900 Jul 10 15:47 archive.tgz
[root@VM-8-11-centos tmp]# 
  • 配置文件中包含我们希望纳入归档的所有目录的绝对路径
# 1.查看配置文件内容。(Does_not_exist 表示不存在的路径,用于稍后脚本的测试。)
[root@VM-8-11-centos tmp]# cat file_path.conf 
/home/jan/BackupScriptProject/ 
/home/jan/Downloads/ 
/home/jan/Does_not_exist/ 
/home/jan/PythonConversion/
[root@VM-8-11-centos tmp]# 
  • 为了让脚本读取配置文件,将每个目录名加入归档列表中,这需要用到 read 命令。并使用 exec 命令来重定向标准输入(STDIN):
# $config_file:读取配置文件的每一条记录。
exec 0<$config_file 
read -r file_name

# 循环读:一旦(read)命令读到配置文件的末尾,就会$?变量返回一个非0状态码。这时,脚本会退出(while)循环。
while [ $? -eq 0 ]; do
    # TODO
    read -r file_name
done
  • 在 while 循环中,需要做两件事:首先,必须将目录名加入归档列表;其次,但更重要的是,要检查目录是否存在
    # 确保是文件或者目录。
    if [ -f $file_name ] || [ -d $file_name ]; then
        # 添加至集合。
        file_list="$file_list $file_name"
    else
        # 不是文件或者目录则进行提示。
        echo
        echo "$file_name, does not exist."
        echo "Obviously, I will not include it in this archive."
        echo "It is listed on line $file_no of the config file."
        echo "Continuing to build archive list..."
        echo
    fi
    # file_no 记录在归档配置文件的哪一行中含有不正确或缺失的文件或目录。
    file_no=$((file_no + 1))

1.2 创建按日归档文件的存放位置

如果只需要备份少量文件,那么将这些归档文件放在个人目录中即可。但如果要对多个目录进行备份,则最好还是创建一个集中的归档仓库目录。

  • 创建仓库及关联组过程
# 1.创建归档仓库目录。
[root@VM-8-11-centos home]# sudo mkdir /archive
[root@VM-8-11-centos home]#

# 2.检查创建好的归档仓库目录。
[root@VM-8-11-centos home]# ls -ld /archive/
drwxr-xr-x 2 root root 4096 Jul 10 17:28 /archive/
[root@VM-8-11-centos home]# 

# 3.添加组(Archivers)并关联用户(jan),最后再对组添加读写执行权限。
# 将用户添加到 Archivers 组后,用户必须先登出然后再登入,这样才能使组成员关系生效。
# 现在只要是该组的成员,无须超级用户权限就可以在目录中创建文件了。
[root@VM-8-11-centos home]# sudo groupadd Archivers
[root@VM-8-11-centos home]# 
[root@VM-8-11-centos home]# sudo chgrp Archivers /archive
[root@VM-8-11-centos home]# 
[root@VM-8-11-centos home]# ls -ld /archive
drwxr-xr-x 2 root Archivers 4096 Jul 10 17:28 /archive
[root@VM-8-11-centos home]# 
[root@VM-8-11-centos home]# sudo usermod -aG Archivers jan
[root@VM-8-11-centos home]# 
[root@VM-8-11-centos home]# sudo chmod 775 /archive/
[root@VM-8-11-centos home]# 
[root@VM-8-11-centos home]# ls -ld /archive/
drwxrwxr-x 2 root Archivers 4096 Jul 10 17:28 /archive/
[root@VM-8-11-centos home]# 

# 4.移动配置文件到归档仓库目录。
[root@VM-8-11-centos tmp]# mv file_path.conf /archive/
[root@VM-8-11-centos tmp]# 
[root@VM-8-11-centos tmp]# ls /archive/
file_path.conf
[root@VM-8-11-centos tmp]# 

1.3 创建按日归档的脚本

Daily_Archive.sh 脚本会自动在指定位置创建一个归档文件,并使用当前日期作为该文件的唯一标识。

  • 脚本内容
#!/bin/bash
####################  相关信息  ####################
# 包名通过日期区分。
today=$(date +%y%m%d)
backupfile=archive$today.tar.gz
# 配置文件及归档的目标目录。
config_file=/archive/file_path.conf
destination=/archive/$backupfile

####################  处理逻辑  ####################
# 确保配置文件是存在的。
if [ -f $config_file ]; then
    # 存在则什么也不用做。
    echo
else
    # 不存在则进行提示。
    echo
    echo "$config_file does not exist."
    echo "Backup not completed due to missing Configuration File"
    echo
    exit
fi
# 记录行数。
file_no=1
# 从配置文件中获取输入。
exec 0<$config_file
read -r file_name
# 循环读。
while [ $? -eq 0 ]; do
    # 确保是文件或者目录。
    if [ -f $file_name ] || [ -d $file_name ]; then
        # 添加至集合。
        file_list="$file_list $file_name"
    else
        # 不是文件或者目录则进行提示。
        echo
        echo "$file_name, does not exist."
        echo "Obviously, I will not include it in this archive."
        echo "It is listed on line $file_no of the config file."
        echo "Continuing to build archive list..."
        echo
    fi
    # 记录行号。
    file_no=$((file_no + 1))
    # 读取下一条。
    read -r file_name
done
#
echo "Starting archive..."
echo
# 判断归档文件列表是否为空。
if [ -n "${file_list[*]}" ]; then
    tar -czf $destination $file_list 2>/dev/null
    echo "Archive completed"
    echo "Resulting archive file is: $destination"
    echo
else
    echo "file_list is empty."
fi
# 退出。
exit

1.4 运行按日归档的脚本

在测试脚本之前,别忘了修改脚本文件的权限。文件属主必须被赋予可执行权限(x)才能运行脚本.

  • 运行脚本
# 1.添加执行权限。
[root@VM-8-11-centos archive]# ls -og Daily_Archive.sh 
-rw-r--r-- 1 1533 Jul 13 15:38 Daily_Archive.sh
[root@VM-8-11-centos archive]# 
[root@VM-8-11-centos archive]# chmod u+x Daily_Archive.sh 
[root@VM-8-11-centos archive]# 
[root@VM-8-11-centos archive]# ls -og Daily_Archive.sh 
-rwxr--r-- 1 1533 Jul 13 15:38 Daily_Archive.sh
[root@VM-8-11-centos archive]#

# 2.当前目录下的文件。
[root@VM-8-11-centos archive]# ls 
Daily_Archive.sh  file_path.conf  temp.sh

# 3.运行脚本。
[root@VM-8-11-centos archive]# ./Daily_Archive.sh 


/home/jan/Does_not_exist/, does not exist.
Obviously, I will not include it in this archive.
It is listed on line 3 of the config file.
Continuing to build archive list...

Starting archive...

Archive completed
Resulting archive file is: /archive/archive230713.tar.gz

[root@VM-8-11-centos archive]#

# 4.生成了压缩归档文件。
[root@VM-8-11-centos archive]# ls 
archive230713.tar.gz  Daily_Archive.sh  file_path.conf  temp.sh

# 5.查看 tar 压缩文件的内容。
[root@VM-8-11-centos archive]# 
[root@VM-8-11-centos archive]# tar -tf archive230713.tar.gz 
home/jan/BackupScriptProject/
home/jan/BackupScriptProject/1.txt
home/jan/Downloads/
home/jan/Downloads/2.txt
home/jan/PythonConversion/
home/jan/PythonConversion/3.txt
[root@VM-8-11-centos archive]# 
  • 由于这是一个重要的脚本,因此请考虑使用 anacron 程序,以便让它每天都运行,而无须担心是否忘记启动脚本。
  • 提示
    • tar 只是使用 bash shell 命令在系统中执行备份的一种方法。
    • 有一些其他的实用程序(或命令组合)也许能更好地满足你的需求,比如 rsync
    • 要查看可能有助于备份工作的各种实用工具名称,可以在命令行提示符下输入 man -k archive 和 man -k copy。

二、创建按小时归档的脚本

如果你处于文件改动非常频繁的高产量生产环境中,那么按日归档可能无法满足需求。

2.1 目录层级

  • 按小时备份文件时,如果依然使用 date 命令为每个归档文件加入时间戳,那么随着日积月累在同一目录下的文件会越来越多,不方便查阅。
  • 因此我们可以对目录层级进行优化。不必将所有的归档文件都放到同一目录中,可以为归档文件创建一个目录层级
  • 示意图
                                                                 日期

月份 +---------+
+----->+ day|01 |
+---------+ | +---------+
| | |
+------------+ 01月 +---------+
| | | |
基点 | +---------+ | +---------+
| +----->+ day|02 |
+----------+ | +---------+ +---------+
| | | | |
| +---------------------+ 02月 |
| | | | |
+----------+ | +---------+
|
/archive/hourly | +---------+
| | |
+------------+ ... |
| |
+---------+

  • 这个归档目录包含了与一年中的各个月份相对应的子目录并以月份命名,而每月的目录中又包含与当月各天相对应的子目录并以天的序号命名。

  • 这样你只需给每个归档文件加上时间戳,然后将其放入与月日对应的目录中即可。

  • 首先必须创建新目录 /archive/hourly 并设置适当的权限

# 1.创建hourly目录。
[root@VM-8-11-centos ~]# sudo mkdir /archive/hourly
[root@VM-8-11-centos ~]# 

# 2.关联该目录的所属组(Archivers)。
[root@VM-8-11-centos ~]# sudo chgrp Archivers /archive/hourly
[root@VM-8-11-centos ~]# 

# 3.列出目录本身的信息,包括所有权信息和所属组信息。
[root@VM-8-11-centos ~]# ls -ogd /archive/hourly/
drwxr-xr-x 2 4096 Jul 14 11:09 /archive/hourly/
[root@VM-8-11-centos ~]# 

# 4.赋予主和组的读写执行权限。
[root@VM-8-11-centos ~]# sudo chmod 775 /archive/hourly
[root@VM-8-11-centos ~]# 

# 5.权限赋予完成。
[root@VM-8-11-centos ~]# ls -ogd /archive/hourly/
drwxrwxr-x 2 4096 Jul 14 11:09 /archive/hourly/
[root@VM-8-11-centos ~]# 
  • 新目录设置好之后,需要将按小时归档的配置文件 file_path.conf 移到该目录中
# 1.当前所在目录。
[root@VM-8-11-centos archive]# pwd
/archive
[root@VM-8-11-centos archive]# 

# 2.将按小时归档的配置文件移到当前目录。
[root@VM-8-11-centos archive]# mv /archive/file_path.conf /archive/hourly/
[root@VM-8-11-centos archive]# 

# 3.配置文件移动完成。
[root@VM-8-11-centos archive]# cd /archive/hourly/
[root@VM-8-11-centos archive]# 
[root@VM-8-11-centos hourly]# ls
file_path.conf
[root@VM-8-11-centos hourly]#  
  • 只需要修改脚本的相关信息部分(处理逻辑部分与按日归档的脚本一致):
[root@VM-8-11-centos hourly]# cat Hourly_Archive.sh 
#!/bin/bash
####################  相关信息  ####################
# 基点目录。
basedest=/archive/hourly
# 月日及时分。
month=$(date +%m)
day=$(date +%d)
time=$(date +%k%M)
# 递归创建目录及子目录。
mkdir -p $basedest/$month/$day
# 配置文件及归档的目标目录。
config_file=/archive/hourly/file_path.conf
destination=$basedest/$month/$day/archive$time.tar.gz

####################  处理逻辑  ####################
...

2.2 运行按小时归档的脚本

最好通过 date 命令来获取当前的小时数和分钟数,有了这些信息才能验证最终的归档文件名的正确性。

  • 运行脚本
# 1.赋予执行权限。
[root@VM-8-11-centos hourly]# chmod u+x Hourly_Archive.sh 
[root@VM-8-11-centos hourly]# 

# 2.先通过命令检查当前的时和分。
[root@VM-8-11-centos hourly]# date +%k%M
1419
[root@VM-8-11-centos hourly]# 

# 3.运行脚本。
[root@VM-8-11-centos hourly]# ./Hourly_Archive.sh 


/home/jan/Does_not_exist/, does not exist.
Obviously, I will not include it in this archive.
It is listed on line 3 of the config file.
Continuing to build archive list...

Starting archive...

Archive completed
Resulting archive file is: /archive/hourly/07/14/archive1419.tar.gz

[root@VM-8-11-centos hourly]# 

# 4.查看 tar 压缩文件的内容。
[root@VM-8-11-centos hourly]# tar -tf /archive/hourly/07/14/archive1419.tar.gz 
home/jan/BackupScriptProject/
home/jan/BackupScriptProject/1.txt
home/jan/Downloads/
home/jan/Downloads/2.txt
home/jan/PythonConversion/
home/jan/PythonConversion/3.txt
[root@VM-8-11-centos hourly]# 

 

收录于合集 #Linux与Shell
 20
上一篇gawk 进阶下一篇删除账户脚本
阅读 486
饺子泡牛奶
 
posted @ 2023-07-16 20:52  往事已成昨天  阅读(75)  评论(0编辑  收藏  举报