《LinuxShell脚本攻略》,Chap-6:Plan B
简介
提取快照和备份数据都是重要的工作,我们可以通过shell脚本来实现备份自动化。
归档和压缩对于SA来说同样很重要,有多种压缩格式。
加密是一种保护数据的方法,为了减少加密数据的大小,文件在加密前通常需要先归档和压缩。
用tar归档
tar
命令可以用来归档文件(tar archives tar)。可以将多个文件和文件夹打包为单个文件,同时还能保留所有的文件属性。
由tar
命令创建的文件通常称为tarball。
#归档文件,-c(create file)
tar -cf 1.tar [sources] #-f(specify filename)指定文件名
#文件名必须紧跟在-f之后
tar -cvf txt.tar *.txt #-v(verbose)详细信息
#向已归档文件中添加文件,-r
tar -rvf txt.tar *.html
#列出归档文件中的内容,-t
tar -tf txt.tar #列出归档内容
tar -tvf txt.tar #列出内容详细信息
#从归档文件中提取文件或文件夹,-x(exact)
tar -xf txt.tar #默认提取到当前目录
#-C指定提取目录
tar -xvf txt.tar -C /dir/path
#只提取归档中特定文件
tar -xf txt.tar 1.txt 1.html -C /tmp #只会提取1.txt和1.html文件
#在tar中使用stdin和stdout
tar -cvf - *.text | tar -xvf - -C /tmp
#拼接两个归档文件,-A
tar -Af txt.tar html.tar
tar -tvf txt.tat #验证是否成功
#添加选项,可以将指定的任意文件加入到归档文件中。如果同名文件已存在,不会覆盖源文件,那么结果就是归档中包含了多个同名文件
#通过检查时间戳来更新对党文件中的内容,-u
#只有比归档文件中同名文件 更新(newer) 才添加
tar -uvf html.tar 1.html
#比较归档文件与文件系统中的内容,-d
tar -df txt.tar 1.txt 2.txt
#从归档文件中删除文件,--delete
tar -f txt.tar --delete 1.txt 2.txt
#从归档文件中排除部分文件,--exclude
tar -cf all.tar ./* --exclude="*.html" #排除.html文件
tar -cvf txt.tar *.txt --exclude="1.txt"
#打印总字节数,--totals
tar -cf all.txt ./* --totals
#压缩tar归档文件,指定不同压缩格式
#-z, .tar.gz
#-j, .tar.bz2
#--lzma, .tar.lzma,
#.tar.lzo
tar -czvf txt.tar.gzip *.txt
tar -xzvf txt.tar -C /dir/path
用cpio归档
cpio
是类似于tar的另一种归档格式。它多用于RPM软件包、Linux内核和initramfs文件等。
cpio通过stdin获取输入,并将归档写入stdout。
touch file{1..4}
echo file1 file2 file3 file4 | cpio -ov file.cpio
#-o指定输出,-v打印归档文件列表
#-i指定输入,-t列出归档中文件
cpio -it < file.cpio
用gunzip或gzip压缩
gzip是GNU/Linux下常用压缩格式。gzip
,gunzip
都可处理gzip压缩文件类型。
gzip
只能够压缩单个文件,而无法对目录和多个文件进行归档。因此需要先交给tar
,然后再用gzip
压缩
gzip file #file.gz,会覆盖原文件
gunzip file.gz #file,也会删除原文件
#列出压缩文件的属性信息,-l
gzip -l file.gz
#指定gzip的压缩级别,--fast或--best
--fast 最低压缩比,最快速度完成
--best 最高压缩比,最慢速度完成
#将gzip与归档文件结合,-z
tar -czvf txt.tar.gzip ./*.txt
#-a指定从文件扩展名自动判断压缩格式
tar -cavf txt.tar.gzip ./*.txt
#tar只能从命令行中接收有限个文件,要解决这个问题,可以写一个循环并添加-r选项
#解压缩,-x
tar -xzvf txt.tar.gzip
tar -xavf txt.tar.gzip -C /dir/path
用bunzip或bzip压缩
bzip2
通常能够生成比gzip更小(压缩比更高)的文件。
bzip2 file #file.bz2,同理会覆盖原文件
bzip2 file -k #保留原文件
bunzip2 file.bz2 #解压缩
bunzip file.bz2 -k
#从stdin读入并写到stdout
cat file | bzip2 -c > file.bz2
#将bzip2与归档文件结合,-j
tar -cvjf 1.tar.bz2 ./1.*
tar -cavf 1.tar.bz2 ./1.* #-a根据文件扩展名自动判断压缩格式
tar -xjvf 1.tar.bz2
tar -xavf 1.tar.bz2 -C /tmp
#压缩比
#从1级(速度最快,压缩率最低)到9级
bzip -9 -k file
#对成千上万的文件进行归档,需要借助 循环和-r选项
lzma压缩
lzma
是一个较新的压缩工具,它提供了比gzip或bzip2更好的压缩率。
xz, unxz, xzcat, lzma, unlzma, lzcat - Compress or decompress .xz and .lzma files
lzma file #file.lzma,同样也会删除原文件
lzma file -k #保留原文件
unlzma file.lzma
#从stdin读入并写入stdout
cat file | lzma -C > file.lzma
#与tar相结合,--lzma
tar -cvf 1.tar.lzma ./1.* --lzma
tar -cavf 1.tat.lzma ./1.* #自动判断
tar -xvf 1.tar.lzma --lzma
tar -xavf 1.tar.lzma -C /tmp
#压缩率
#从1级到9级(压缩级别最高,速度最慢)
#对成千上万的文件,需要使用循环和-r选项
zip归档和压缩
zip
在Linux下不如gzip
,bzip2
那么广泛,但在Internet上的文件通常都采用这种格式。
zip - package and compress (archive) files
zip file.zip file
unzip file.zip
#与lzma,gzip,bzip2相比,zip完成后不会删除原文件
#对目录和文件进行递归操作,-r
zip -r dir.zip /root/test ./file
#向归档文件中增加内容,-u
zip dir.zip -u newfile
#从压缩文件中删除内容,-d
zip -d dir.zip file
#列出归档文件中内容
unzip -l dir.zip
超高压缩率的squashfs文件系统
squashfs
是一种只读型的超高压缩率文件系统。这种文件系统能够将 2GB-3GB的数据压缩成一个700MB的文件。
你有没有想过Linux Live CD是怎样运行的?当Live CD启动后,它会加载一个完整的Linux环境。这就是利用了一种被称为squashfs的只读型压缩文件系统。它将根文件系统保存在一个压缩过的文件系统文件中。这个文件可以使用环回的形式来挂载并对其中的文件进行访问。一次当进程需要某些文件,可以将它们解压,然后载入内存中使用。
如果需要构建一个定制的Live OS,或是需要超高压缩率的文件并且无需解压就可以访问文件,那么squashfs的相关知识就能派上用场。要解压个头较大的压缩文件,需要花费不少时间。但如果将文件以环回形式挂载,速度就飞快,因为只有出现访问请求的时候,对应的那部分压缩文件才会被解压缩。而普通的解压缩方式是首先压缩所有的数据。
环回文件系统就是指那些在文件中而非物理设备中创建的文件系统。比如我们可以创建一个文件,然后把这个文件格式化为我们常见ntfs、exfat或者ext4等文件系统格式,然后把它挂载在一个目录上使用。
如果你有一张Ubuntu CD,可以在CDRom Root/casper/filesystem.squashfs中找到文件.squashfs。
squashfs在内部采用了gzip和lzma这类压缩算法。
mksquashfs - tool to create and append to squashfs filesystems
yum install squashfs-tools -y
#创建squashfs文件
mksquashfs source compressfile.squashfs
mksquashfs /etc etc.squashfs
#/etc(67M) --> etc.suqashfs(18M)
#要挂载squashfs文件,利用环回形式进行挂载
mkdir /mnt/squash
mount -o loop etc.squashfs /mnt/squash
#此处挂载使用etc.squashfs文件系统
#如果直接查看etc.squashfs,就是一个普通文件,但是挂在以后所有文件都出现了
umount /mnt/squash
#在创建squashfs文件时排除指定文件,-e
mksquashfs /etc etc.squashfs -e /etc/passwd /etc/shadow /etc/*.txt
#在挂载之后就没有相关文件了
加密工具与散列
加密技术主要用于防止数据遭受未经授权的访问。
Linux下某些工具用于执行加密和解密,使用加密算法散列值来验证数据完整性。
crypt
, gpg
, base64
, md5sum
, sha1sum
, openssl
的用法
ccypt
ccrypt是为了取代UNIX crypt而设计的,这个实用工具可用于文件和数据流加密及解密。
ccrypt - encrypt and decrypt files and streams
ccrypt 1.txt #会要求输入口令(encryption key)
#之后会生成1.txt.cpt覆盖原文件
#更改key,-x
ccrypt -x 1.txt.cpt #输入old key和new key
#解密,-d(--decrypt)
ccrypt -d 1.txt.cpt #输入key解密
gpg
gpg(GNU privacy guard,GNU隐私保护),是一种应用广泛的加密方案。
它采用签名密钥技术保护文件内容,只有经过认证的用户才能访问数据。我们对gpg签名早已耳熟能详。
gpg - OpenPGP encryption and signing tool
#加密,-c(--symmetric)对称加密
gpg -c file #会要求输入口令(Passphrase),生成file.gpg
#解密
gpg file.gpg
base64
base64
是一组类似的编码方案(encoding scheme),它通过将ASCII字符转换成以64为基数的形式(radix-64 representation)来用ASCII字符串描述二进制数据。base64可用来对 编码和解码 base64字符串。
base64 - base64 encode/decode data and print to standard output
#将文件编码为base64格式
base64 file > outputfile
cat file | base64 > outputfile
#解码,-d
base64 -d outputfile > file
md5sum与sha1sum
md5sum
和 sha1sum
都是单向散列算法(unidirecrional hash algorithm),均无法逆推出原始数据。
它们通常用于验证数据完整性或为特定数据生成唯一的密钥,因为通过分析文件内容,它们可以为每个文件生成一个唯一的密钥。
这种类型的散列算法是存储密码的理想方案。密码使用其对应的散列值来存储。如果某个用户需要认证,读取该用户提供的密码并转换成散列值,然后将其与之前存储的散列值进行比对。
将密码以明文的形式存储是非常危险的事情,它面临密码泄露的危险。而因为 md5sum和sha1sum 是单向散列算法,所以密码使用散列值存储是很安全的。
echo "1.txt" > 1.txt
md5sum 1.txt #生成密钥到stdout
#39061daa34ca3de20df03a88c52530ea 1.txt
sha1sum file #生成密钥到stdout
#659fcbc505db207c03b5c4c0b6981d63286abe21 1.txt
#查看/etc/shadow中密码的散列值
awk 'NR==1' /etc/shadow | awk -F: '{print $2}' #root密码散列
shadowlike散列(salted散列)
shadow密码通常都是salted密码,所谓SALT就是额外的一个字符串,用来起一个混淆的作用,使加密更加不同里被破解。salt由一些随机位组成,被用作密钥生成函数的输入之一,以生成密码的salted散列值。
#/etc/passwd里面的密码散列类型就是salted散列
#查看root密码对应的散列值
head -1 /etc/shadow
root:$6$ZlHRCZG2iRwQUXAu$RAEDH97nPdZB2RK20npua6Qf6jB7osatoC99ow3LtPQ6aORdLISYC7/4iTYU162emkQLt4ZafdgjyAeoSB7IU0::0:99999:7:::
#openssl - OpenSSL command line tool
#shadow密码是使用openssl生成
#将SALT_STRING替换为随机字符串,同时将pass替换成你想测试的密码
openssl -1 -salt SALT_STRING passwd
用rsync备份系统
rsync
借助差异计算以及压缩技术来最小化数据传输量。相较于cp
命令,它的优势在于使用了高效的差异算法(difference algorithm)。
它还支持网络数据传输。在进行复制的同时,rsync会比较源端和目的端的文件,只有当文件有更新是才进行复制。默认情况下,rsync并不会在目的端删除源端已不存在的文件。
rsync - a fast, versatile, remote (and local) file-copying tool
inotifywait - wait for changes to files using inotify
#-a进行归档,-v详细信息
rsync -av source destination
rsync -av /etc /tmp
#异地cp
rsync -av source username@host:PATH
rsync -av username@host:PATH destination
#rsync借助于ssh,可以使用ssh无秘钥认证
rsync -av /etc [email protected]:~
#-z, --compress compress file data during the transfer
rsync -avz [email protected]:/etc /tmp
#注意,路径格式
rsync /etc /tmp #整个/etc目录
rsync /etc/ /tmp #/etc目录下所有内容
#显示进度,--progress
rsync -avz --progress /etc /tmp
#排除部分文件,--exclude
rsync -avz /etc /tmp --exclude=/etc/nginx --exclude "*.txt"
#更新rsync时,删除不存在的文件,--delete
#默认情况下,rsync并不会在目的端删除源端已不存在的文件
rsync -avz /etc [email protected]:~ --delete
#定期调度
crontab -e
0 */10 * * * rsync -avz /etc user@host:PATH
#实时同步,inotifywait+rsync
yum install inotify-tools -y
#-m(monitor),-r(recursive),-q(--quiet)静默模式,-e(event)
vi inotify_rsync.sh
inotifywait -mrq -e creat,delete,modify,move --exclude "^.*\.filepart$" /etc
rsync -az --exclude=".*" --exclude="*.swp" --exclude=".filepart" --delete /etc /tmp > /dev/null 2>&1
用Git备份版本控制
维护和恢复变更最好的方法是使用版本控制系统。由于代码变更频繁,版本控制系统多用于软件开发和代码维护。
Git(GNU it)是有名气也是最高效的版本控制系统。我们可在非编程环境下用Git备份普通文件。
git - the stupid content tracker
mkdir /home/zhang/gittest
cd /home/zhang/gittest
#在源主机中添加用户信息
git config --global user.name "username" #设置用户名
git config --global user.email "[email protected]" #设置邮箱
#创建一个空的Git版本库或初始化一个老版本
git init
#记录变更到版本库
git commit
#添加远程git目录并同步备份
git remote add origin user@host:/home/zhang/gittest
#为git跟踪(git tracking)添加或删除文件
#add,添加内容至索引
git add *
#git add *.txt; git add *.ph #添加部分文件
#删除不需要跟踪的文件和文件夹
#rm,从工作去和索引删除文件
git rm file
#git rm *.txt
#检查点或创建备份点(check point)
git commit -m "Commit Message"
#push,更新远程
git push
#用Git恢复数据
#log,显示提交日志
git log
#返回之前某个版本或状态
git checkout xxxxxxxx(Commit ID)
#clone,克隆一个版本库到本地
git clone URL
git clone user@host:PATH
用dd克隆磁盘
dd
命令能用于克隆任何类型的磁盘,如硬盘、闪存、CD、DVD及软盘。
可能需要创建所有分区的副本而不仅仅是复制内容,包括硬盘分区、引导记录、分区表等信息。
使用dd的时候,要留意参数的顺序。错误的参数会损毁全部数据。dd基本上算是一个比特流复制器(bitstream duplicator),它可以将来自磁盘的比特流写入文件,也可以将来自文件的比特流写入硬盘。
dd - convert and copy a file
dd if=source of=target bs=block_size count=count
#bs块大小,count块数
dd if=/tmp/centos7.iso of=/dev/sdc
#/dev/zero是一个字符设备,它总是返回字符'\0'
dd if=/dev/zero of=./file bs=10m count=100
#用环回(loop back)方法可将任何由dd生产的文件镜像进行挂载
mount -o loop file /mnt