《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 zhang@192.168.1.11:~
#-z, --compress compress file data during the transfer
rsync -avz zhang@192.168.1.11:/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 zhang@192.168.1.1:~ --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 "someone@example.com" #設置郵箱
#創建一個空的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