摘自 Linux Shell 脚本攻略 第七章 B计划
使用 tar 归档
tar命令可以归档文件。它最初是设计用来将数据存储在磁带上,因此其名字也来源于Tape ARchive。tar可以将多个文件和文件夹打包为单个文件,同时还能保留所有的文件属性,如所 有者、权限等。由tar创建的文件通常称为tarball。在这则攻略里,我们将学习如何使用tar创建 归档文件
归档:把多个文件组合到一个文件中。归档好处是,把文件数目变少,有利于降多个文件作为电子邮件附件发送,以及备份文件
压缩:利用算法将文件有损或无损地处理,以达到保留最多文件信息,而令文件体积变小。压缩好处就是节约硬盘空间,以及减小电子邮件附件的大小,提高传输效率
用tar创建归档文件
$ tar -cf output.tar coco.sh
$ ls output.tar
output.tar
$ tar -cf archive.tar file1 file2 file3 folder1 ..
选项-c表示创建新的归档文件。
选项-f表示归档文件名,该选项后面必须跟一个文件 名称
选项-t可以列出归档文件中所包含的文件
$ tar -tf output.tar
coco.sh
选项-v或-vv参数可以在命令输出中加入更多的细节信息
这个特性叫作“冗长模式(v, verbose)”或“非常冗长模式(vv,very verbose)”。
对于能够在终端中生成报告的命令, -v是一个约定的选项。该选项能够显示出更多的细节,例如文件权限、所有者所属的分 组、文件修改日期等信息
$ tar -tvf output.tar
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
文件名必须紧跟在-f之后出现,而且-f应该是选项中的最后一个。假如你 希望使用冗长模式,应该像这样写
$ tar -cvf output.tar file1 file2 file3 folder1 ..
向归档文件中追加文件
- 选项-r可以将新文件追加到已有的归档文件末尾:
$ tar -rvf output.tar file1.txt
file1.txt
$ tar -tvf output.tar
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
从归档文件中提取文件或目录
- 选项-x可以将归档文件的内容提取到当前目录
$ ls coco.sh
ls: cannot access 'coco.sh': No such file or directory
$ tar -xf output.tar
$ ls coco.sh
coco.sh
# 使用-x时,tar命令将归档文件中的内容提取到当前目录。我们也可以用选项-C来指定将文 件提取到哪个目录
$ tar -xf archive.tar -C /path/to/extraction_directory
该命令将归档文件的内容提取到指定目录中。它提取的是归档文件中的全部内容。我们可以通过 将文件名作为命令行参数来提取特定的文件
$ tar -xvf file.tar file1 file4
在tar中使用stdin和stdout
$ tar cvf - files/ | ssh user@example.com "tar xv -C Documents/"
在上面的例子中,对files目录中的内容进行了归档并将其输出到stdout(由-指明),然后 提取到远程系统中的Documents目录中
拼接两个归档文件
$ tar -tf original.tar
file1.txt
$ tar -Af original.tar output.tar
$ tar -tvf original.tar
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
通过检查时间戳来更新归档文件中的内容
追加选项(-r)可以将指定的任意文件加入到归档文件中。如果同名文件已经存在,那么归 档文件中就会包含两个名字一样的文件。我们可以用更新选项-u指明:只添加比归档文件中的同 名文件更新(newer)的文件
$ tar -uf original.tar file1.txt
$ tar -tvf original.tar
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
-rw-rw-r-- amlogic/amlogic 12 2021-11-27 17:40 file1.txt
-rw-rw-r-- amlogic/amlogic 12 2021-11-27 17:43 file1.txt
比较归档文件与文件系统中的内容
选项-d可以将归档中的文件与文件系统中的文件作比较。这个功能能够用来确定是否需要创建新的归档文件
$ tar -df original.tar
file1.txt: Mod time differs
file1.txt: Size differs
file1.txt: Mod time differs
file1.txt: Size differs
file1.txt: Mod time differs
从归档中删除文件
$ tar -tvf original.tar
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
-rw-rw-r-- amlogic/amlogic 10 2021-11-23 16:27 file1.txt
-rw-rw-r-- amlogic/amlogic 12 2021-11-27 17:40 file1.txt
-rw-rw-r-- amlogic/amlogic 12 2021-11-27 17:43 file1.txt
$ tar -f original.tar --delete file1.txt
$ tar -tvf original.tar
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
压缩tar归档文件
tar命令默认只归档文件,并不对其进行压缩。不过tar支持用于压缩的相关选项。压缩能 够显著减少文件的体积。归档文件通常被压缩成下列格式之一
- gzip格式:file.tar.gz或file.tgz。
- bzip2格式:file.tar.bz2。
- Lempel-Ziv-Markov格式:file.tar.lzma。
不同的tar选项可以用来指定不同的压缩格式
- -j指定bunzip2格式;
- -z指定gzip格式;
- –lzma指定lzma格式。
为了让tar支持根据扩展名自动选择压缩算法,使用-a或–auto-compress 选项
$ tar -acvf coco.tar.gz coco.sh
coco.sh
$ tar -tvf coco.tar.gz
-rwxrwxr-x amlogic/amlogic 355 2021-11-25 15:43 coco.sh
在归档过程中排除部分文件
$ tar -cf arch.tar * --exclude "*.txt"
# 也可以将需要排除的文件列表放入文件中,同时配合选项-X
$ cat list
filea
fileb
$ tar -cf arch.tar * -X list
注意,模式应该使用双引号来引用,避免shell对其进行扩展
排除版本控制目录
tar的选项–exclude-vcs可以在归档时排除版本控制相关的文件和目录
$ tar --exclude-vcs -czvvf source_code.tar.gz eye_of_gnome_svn
打印总字节数
选项-totals可以打印出归档的总字节数
$ tar -cvf coco.tar coco.sh --totals
coco.sh
Total bytes written: 10240 (10KiB, 11MiB/s)
使用 cpio 归档
cpio类似于tar。它可以归档多个文件和目录,同时保留所有的文件属性,如权限、文件所 有权等。cpio格式被用于RPM软件包(Fedora使用这种格式)、Linux内核的initramfs文件(包含 了内核镜像)等。这则攻略将给出几种cpio的用法
# 创建测试文件
$ touch file1 file2 file3
# 归档测试文件
$ ls file* | cpio -ov > archive.cpio
file1
file2
file3
1 block
# 列出cpio归档文件中的内容
$ cpio -it < archive.cpio
file1
file2
file3
1 block
# 从cpio归档文件中提取文件
$ rm file1
$ rm file2
$ rm file3
$ cpio -id < archive.cpio
1 block
$ ls file*
file1 file2 file3
对于归档命令cpio
- -o指定了输出
- -v用来打印归档文件列表
- -i用于指定输入
- -t用于列出归档文件中的内容
使用 gzip 压缩数据
gzip和gunzip可以分别用于压缩与解压缩
gzip 默认情况下不保留原文件
使用gzip压缩文件
$ gzip test
$ ls test*
test_copy1 testfile test.gz
解压缩gzip文件
$ gunzip test.gz
$ ls test
test
列出压缩文件的属性信息
$ gzip -l test.gz
compressed uncompressed ratio uncompressed_name
31 6 -33.3% test
gzip命令可以从stdin中读入文件并将压缩文件写出到stdout
# 从stdin读入并将压缩后的数据写出到stdout
$ cat test |gzip -c > test.gz
# 选项 -c用来将输出指定到stdout。该选项也可以与cpio配合使用
$ ls * | cpio -o | gzip -c > cpiooutput.gz
$ zcat cpiooutput.gz | cpio -it
我们可以指定gzip的压缩级别。–fast或–best选项分别提供最低或最高的压缩率
$ gzip --fast test
压缩归档文件
第一种方法
$ tar -czvvf archive.tar.gz [FILES]
# 或者
$ tar -cavvf archive.tar.gz [FILES]
# 选项-z指明用gzip进行压缩,选项-a指明根据文件扩展名推断压缩格式
第二种方法
# 首先,创建一个tar归档文件
$ tar -cvvf archive.tar [FILES]
# 压缩tar归档文件
$ gzip archive.tar
下面的命令可以提取经由gzip压缩的归档文件中的内容
$ tar -xavvf archive.tar.gz -C extract_directory
zcat——直接读取gzip格式文件
zcat命令无需经过解压缩操作就可以将.gz文件的内容输出到stdout。.gz文件不会发生任 何变化
$ ls test.gz
test.gz
$ zcat test.gz
coco
$ ls test.gz
test.gz
压缩率
我们可以指定压缩率,它共有9级,其中
- 1级的压缩率最低,但是压缩速度最快
- 9级的压缩率最高,但是压缩速度最慢
你可以按照下面的方法指定压缩比
$ gzip -5 test.img
使用bzip2
bzip2在功能和语法上与gzip类似。不同之处在于bzip2的压缩效率比gzip更高,但花费的 时间比gzip更长
- 用bzip2进行压缩
$ bzip2 filename
- 解压缩bzip2格式的文件
$ bunzip2 filename.bz2
- 生成tar.bz2文件并从中提取内容的方法同之前介绍的tar.gz类似
$ tar -xjvf archive.tar.bz2
其中,-j表明该归档文件是以bzip2格式压缩的
使用lzma
lzma的压缩率要优于gzip和bzip2
- 使用lzma进行压缩
$ lzma filename
- 解压缩lzma文件
$ unlzma filename.lzma
- 可以使用–lzma选项压缩生成的tar归档文件
$ tar -cvvf --lzma archive.tar.lzma [FILES]
# 或者
$ tar -cavvf archive.tar.lzma [FILES]
- 将lzma压缩的tar归档文件中的内容提取到指定的目录中
$ tar -xvvf --lzma archive.tar.lzma -C extract_directory
# 其中,-x用于提取内容,--lzma指定使用lzma解压缩归档文件
# 我们也可以用
$ tar -xavvf archive.tar.lzma -C extract_directory
使用 zip 归档及压缩
创建zip格式的压缩归档文件(zip archive)
$ zip coco.zip file1 file2 file3
adding: file1 (stored 0%)
adding: file2 (stored 0%)
adding: file3 (stored 0%)
$ ls coco*
coco.zip
$ zip file.zip file
选项-r可以对目录进行递归式归档
$ zip -r picture.zip picture/
adding: picture/ (stored 0%)
adding: picture/bmp/ (stored 0%)
adding: picture/bmp/无标题.bmp (deflated 21%)
adding: picture/bmp/1.bmp (deflated 45%)
adding: picture/bmp/小点心.bmp (deflated 46%)
adding: picture/bmp/杯子.bmp (deflated 55%)
adding: picture/bmp/无题.bmp (deflated 60%)
adding: picture/bmp/4.bmp (deflated 48%)
...
unzip命令可以从ZIP文件中提取内容
$ unzip file.zip
在完成提取操作之后,unzip并不会删除file.zip(这一点与unlzma和gunzip不同)
选项-u可以更新压缩归档文件中的内容
$ zip file.zip -u newfile
选项-d从压缩归档文件中删除一个或多个文件
$ zip -d arc.zip file.txt
选项-l可以列出压缩归档文件中的内容
$ unzip -l picture.zip
Archive: picture.zip
Length Date Time Name
--------- ---------- ----- ----
0 2021-11-11 16:57 picture/
0 2021-11-03 13:35 picture/bmp/
674094 2021-11-03 13:35 picture/bmp/无标题.bmp
777838 2021-11-03 13:35 picture/bmp/1.bmp
1081554 2021-11-03 13:35 picture/bmp/小点心.bmp
682330 2021-11-03 13:35 picture/bmp/杯子.bmp
750054 2021-11-03 13:35 picture/bmp/无题.bmp
921654 2021-11-03 13:35 picture/bmp/4.bmp
0 2021-11-03 13:35 picture/pic/
325520 2021-11-03 13:35 picture/pic/qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqaaaaaaaaaaaaaaaaaaaaaaaaaZzzzzzzzzzzzzzzzzzzzzz.png
0 2021-11-03 13:35 picture/gif/
150785 2021-11-03 13:35 picture/gif/未命名.gif
12450 2021-11-03 13:35 picture/gif/393020.gif
...
更快的归档工具 pbzip2
我们目前已经看到的多数压缩命令只能利用单个处理器核心。 pbzip2 、 plzip 、 pigz 和 lrzip命令都采用了多线程,能够借助多核来降低压缩文件所需的时间
大多数发行版中都没有安装这些工具,可以使用apt-get或yum自行安装
sudo apt-get install pbzip2
压缩单个文件
$ pbzip2 picture.zip
### 要压缩并归档多个文件或目录,可以使用tar配合pbzip2来实现
$ tar cf coco.tar.bz2 --use-compress-program=pbzip2 for_fun/ picture/
$ ls -l coco.tar.bz2
-rw-rw-r-- 1 amlogic amlogic 59820017 11月 28 17:16 coco.tar.bz2
# 或者
$ tar -c for_fun/ picture/ |pbzip2 -c > coco.tat.bz2
从pbzip2格式的文件中进行提取。
$ pbzip2 -d file1.bz2
# 如果是tar.bz2文件,我们可以利用管道完成解压缩和提取
$ pbzip2 -dc myfile.tar.bz2 | tar -x
手动指定处理器数量
$ pbzip2 -p4 myfile.tar
上面的命令告诉pbzip2使用4个处理器核心
指定压缩比
从选项-1到-9可以指定最快到最好的压缩效果,其中-1的压缩速度最快,-9的压缩率最高
创建压缩文件系统
squashfs程序能够创建出一种具有超高压缩率的只读型文件系统。它能够将2GB~3GB的数 据压缩成一个700MB的文件。Linux LiveCD(或是LiveUSB)就是使用squashfs创建的。这类 CD利用只读型的压缩文件系统将根文件系统保存在一个压缩文件中。可以使用环回方式将其挂 载并装入完整的Linux环境。如果需要某些文件,可以将它们解压,然后载入内存中使用
所有的现代Linux发行版都支持挂载squashfs文件系统。但是创建squashfs文件的话,则 需要使用包管理器安装squashfs-tools
$ sudo apt-get install squashfs-tools
使用mksquashfs命令添加源目录和文件,创建一个squashfs文件
$ mksquashfs SOURCES compressedfs.squashfs
# SOURCES可以是通配符、文件或目录路径。
$ sudo mksquashfs /etc test.squashfs
Parallel mksquashfs: Using 2 processors
Creating 4.0 filesystem on test.squashfs, block size 131072.
[=======================================] 1867/1867 100%
利用环回形式挂载squashfs文件
# mkdir /mnt/squash
# mount -o loop compressedfs.squashfs /mnt/squash
在创建squashfs文件时排除部分文件
# 选项-e可以排除部分文件和目录
$ sudo mksquashfs /etc test.squashfs -e /etc/passwd /etc/shadow
# 其中,选项-e用于将文件/etc/passwd和/etc/shadow排除在外
# 也可以将需要排除的文件名列表写入文件,然后用选项-ef指定该文件
$ cat excludelist
/etc/passwd
/etc/shadow
$ sudo mksquashfs /etc test.squashfs -ef excludelist
# 如果希望在排除文件列表中使用通配符,需要使用-wildcard选项
使用 rsync 备份系统快照
数据备份需要定期完成。除了备份本地文件,可能还涉及远程数据。rsync可以在最小化数 据传输量同时,同步不同位置上的文件和目录。相较于cp命令,rsync的优势在于比较文件修改 日期,仅复制较新的文件。另外,它还支持远程数据传输以及压缩和加密
将源目录复制到目的路径
$ rsync -av source_path destination_path
# 例如
$ rsync -av /home/slynux/data slynux@192.168.0.6:/home/backups/data
- -a表示进行归档操作
- -v(verbose)表示在stdout上打印出细节信息或进度
上面的命令会以递归的方式将所有的文件从源路径复制到目的路径。源路径和目的路径 既可以是远程路径,也可以是本地路径
将数据备份到远程服务器或主机
$ rsync -av source_dir username@host:PATH
下面的命令可以将远程主机上的数据恢复到本地
$ rsync -av username@host:PATH destination
通过网络进行传输时,压缩数据能够明显改善传输效率。我们可以用rsync的选项-z指 定在传输时压缩数据
$ rsync -avz source destination
将一个目录中的内容同步到另一个目录
$ rsync -av /home/test/ /home/backups
这条命令将源目录(/home/test)中的内容(不包括目录本身)复制到现有的backups目 录中
将包括目录本身在内的内容复制到另一个目录中
$ rsync -av /home/test /home/backups
在使用rsync进行归档时排除部分文件
选项–exclude和–exclude-from可以指定不需要传输的文件
–exclude PATTERN
可以使用通配符指定需要排除的文件
$ rsync -avz /home/code/app /mnt/disk/backup/code --exclude "*.o"
或者我们也可以通过一个列表文件指定需要排除的文件。
这需要使用–exclude-from FILEPATH
在更新rsync备份时,删除不存在的文件
默认情况下,rsync并不会在目的端删除那些在源端已不存在的文件。如果要删除这类文件, 可以使用rsync的–delete选项
$ rsync -avz SOURCE DESTINATION --delete
定期备份
你可以创建一个cron任务来定期进行备份
$ crontab -ev
# 添加上这么一行:
0 */10 * * * rsync -avz /home/code user@IP_ADDRESS:/home/backups
上面的crontab项将rsync调度为每10小时运行一次
*/10处于crontab语法中的钟点位(hour position),/10表明每10小时执行一次备份。
如果 */10出现在分钟位(minutes position),那就是每10分钟执行一次备份
差异化归档
到目前为止,我们所描述的备份方法都是完整地复制当时的文件系统。如果在出现问题的时 候你立刻就能发现,然后使用最近的快照来恢复,那么这种方法是有用的。但如果你没有及时发 现问题,直到又制作了新的快照,先前正确的数据已被目前存在错误的数据覆盖,这种方法就派 不上用场了。
文件系统归档提供了一份文件变更的历史记录。如果你需要返回某个受损文件的早期版本, 就用得上它了。
rsync、tar和cpio可以用来制作文件系统的每日快照。但这样做成本太高。每天创建一份 独立的快照,一周下来所需要的存储空间是所备份文件系统的7倍。
差异化备份只需要保存自上次完整备份之后发生变化的文件。Unix中的倾印/恢复(dump/restore) 工具支持这种形式的归档备份。但可惜的是,这些工具是设计用于磁带设备的,所以用起来不太 容易。
find命令配合tar或cpio可以实现相同的功能
使用tar创建第一份完整备份
$ tar -cvz /backup/full.tgz /home/user
# 使用find命令的-newer选项确定自上次完整备份之后,都有哪些文件作出了改动,然后创 建一份新的归档
$ tar -czf day-`date +%j`.tgz `find /home/user –newer /backup/full.tgz`
find 命令会生成自上次创建完整备份( /backup/full.tgz )以来有改动的所有文件的 列表。
date命令会基于儒略历(Julian date)生成一个文件名。因此,当年的第一个差异化备份就是day-1.tgz,1月2日的备份就是day-2.tgz,以此类推。
因为从第一份完整备份往后,越来越多的文件会发生改动,所以每天的差异化归档也会越来 越大。当归档大小超出预期的时候,需要再制作一份新的完整备份。
使用 fsarchiver 创建全盘镜像
fsarchiver可以将整个磁盘分区中的内容保存成一个压缩归档文件。和tar或cpio不同, fsarchiver能够保留文件的扩展属性,可用于将当前文件系统恢复到磁盘中。它能够识别并保 留Windows和Linux系统的文件属性,因此适合于迁移Samba挂载的分区
创建文件系统/分区备份
$ fsarchiver savefs backup.fsa /dev/sda1
# backup.fsa是最终的备份文件,/dev/sda1是要备份的分区
同时备份多个分区
# 还是使用savefs选项,将多个分区作为fsarchiver最后的参数
$ fsarchiver savefs backup.fsa /dev/sda1 /dev/sda2
从备份归档中恢复分区
# 使用fsarchiver的restfs选项
$ fsarchiver restfs backup.fsa id=0,dest=/dev/sda1
# id=0 表明我们希望从备份归档中提取第一个分区的内容, 将其恢复到由 dest=/ dev/sda1所指定的分区
# 从备份归档中恢复多个分区
# 像之前一样,使用restfs选项:
# fsarchiver restfs backup.fsa id=0,dest=/dev/sda1 id=1,dest=/dev/sdb1