摘要
接續〈tar命令的基礎使用〉,本文談點Unix/Unix-like的tar命令的幾個進階使用與範例:- 檔案選擇與排除
- 覆寫控制
- 加密
- 增量備份
- 多重卷冊
- 複製目錄並保留屬性
檔案選擇與排除
本機檔案選擇
以tar封存檔案時,除了可像基礎篇所述直接指定要封存的檔案或目錄,也可將想要備份的檔案列在一清單檔案中,此清單可自行建立編輯,或利用 find 指令來產生,必要時可做適當編輯修改。然後用以下選項讓tar從此清單得知要備份的檔案[1]:- -T, --files-from=FILE
$ find folder_to_archive/ -name '*.txt' > include.txt
$ tar cf archive.tar -T include.txt
或者 find 到的東西透過 | 傳給 tar:
$ find folder_to_archive/ -name '*.txt' | tar cf archive.tar -T-
此處 -T 後的 - 代表著stdio。上例因用了 -T 所以就沒必要在後面指定要封存的檔案,雖然如此,使用此選項的同時,還是可以指定要封存其他檔案或目錄:
$ tar cf archive.tar -T include.txt other_folder_to_archive
當混用多種選項時,記得原則上把 c, x, t 這類操作選項放最前面,要封存的檔案或目錄名稱放最後面,其他的選項放這二者之間。排除
以tar封存檔案時,有時想排除掉某種檔案,以下是與排除相關眾多選項中幾個較常用的[2]:- --exclude=PATTERN:排除某一種檔名形式,如*.bak這類的檔案。
- -X, --exclude-from=FILE:如果要排除的檔名形式較多,可一行一種列在一文字檔中。
- --exclude-vcs:排除VCS (version control system),如git這類版本控制系統的目錄。
- --exclude-vcs-ignores:排除VCS的忽略檔,像.gitignore。
- --no-recursion:tar備份檔案時會包含子目錄,除非加上此選項。
$ tar cf archive.tar --exclude=*.bak --exclude-vcs folder_to_archive/
$ tar cf archive.tar -X excluded.txt folder_to_archive/
$ tar cf ../archive.tar --no-recursion ./*
上例最後一個是備份目前目錄下的所有檔案,排除子目錄,並改在上一層目錄建立備份檔,以避免備份時也包含到備份檔本身。覆寫控制
在解開操作時,有時想避免覆寫取代掉既有的檔案,相關的選項像:- -k, --keep-old-files:別取代掉既有的檔案。
- --keep-newer-files:若是既有的檔案比封存檔中的還新或相同則保留。
$ tar xf archive.tar -k
$ tar xf archive.tar --keep-newer-files
加密
tar本身並不提供加密功能,但可配合其他加密工具程式使用,如gpg, openssl, bcrypt, ccrypt。若覺得這樣做有點麻煩,就改用像zip或7-zip本身有提供加密功能的壓縮程式[3]。本文僅以gpg為例,只用到它最簡單的少許功能,完整使用法可見gpg man page。
gpg的語法形式是:gpg [選項] [命令]
幾個選項:
- --cipher-algo:指定加密演算法。
- -o, --output:指定輸出的檔案。若寫到stdout,以 - 做為檔名。
- -h, --help:顯示簡單的語法說明。
- --version:顯示版號與支援的演算法。
- -c, --symmetric:使用passphrase做對稱式加密。預設使用AES-256。
- -d, --decrypt:解密。
$ gpg --cipher-algo 3des -c test.txt
在圖形桌面環境執行會跳出小視窗,要輸入二次密碼。注意,輸入焦點並不在此小視窗上,還要再以滑鼠點一下。完成後會出現個test.txt.gpg的檔案,若要將其解密並存成另一檔案newfile.txt:
$ gpg -o newfile.txt -d test.txt.gpg
解密時不會問密碼?因為已存在自己家目錄下.gnupg目錄中。總之,檔案給別人解密時就會問密碼。要將folder1目錄以tar做封存並以gpg加密:
$ tar cvzf - folder1/ | gpg -o folder1.tar.gz.gpg -c
將上例的folder1.tar.gz.gpg解密並以tar解開還原到另一個已先建立好的folder2目錄下:
$ gpg -d folder1.tar.gz.gpg | tar xvzf - -C folder2/
增量備份
以tar做增量備份封存時,tar會做些記錄在一個快照檔snapshot file中,以此來決定每次備份之間檔案的異動情形。如此在下回做增量備份時,只備份有變動的檔案,而不是全部。與此工作較相關的選項有:- -g, --listed-incremental=FILE:指定增量備份時所用的快照檔。採用新式GNU格式增量備份。
- --level=NUMBER:指定備份層級,後詳述。
- -G, --incremental:建議只用在解開還原與列示的操作,後述。處理舊式GNU格式增量備份。
備份
做第一次增量備份,由於是第一次,所以事實上也是完整備份:
$ tar cf archive1.tar -g snap folder_to_archive/
此時會建立個名稱為snap的檔案來存放快照,而archive1.tar是level 0備份。對folder_to_archive/目錄中的東西做了修改或新增、刪除之後,做第二次增量備份:
$ tar cf archive2.tar -g snap folder_to_archive/
此時tar先比較folder_to_archive/中的檔案與原snap中的記錄以發現其中的不同,只備份新增與修改過的檔案,然後再把新的記錄寫入snap中。archive2.tar則是level
1的備份;如果往後依此法每做一回增量備份,level都會加1。假定之後想重新重頭開始做增量備份,可將前述的快照檔刪除,再使用前述相同的指令;或是在第一次備份時,指定 --level=0 :
$ tar cf archive1.tar -g snap --level=0 folder_to_archive/
由於增量備份依賴時間戳記,所以若在做備份的同時又修改了檔案時間或是調整系統的時間,可是會出差錯的。還原
延續上例,假定要還原資料,結合使用 -x 與 -g 選項,依序還原即可,tar會還原到備份檔建立時的檔案狀態,會刪除系統中有而備份檔中沒有的檔案。此時tar已沒必要讀取快照檔,因要解出的檔案都在備份檔中,所以 -g 可給予任意參數,通常可用 -g /dev/null;或者改用 -G, --incremental,它可在extract或list操作時做為 -g 的替代。範例:
$ tar xf archive1.tar -g /dev/null
$ tar xf archive2.tar -G
列示
列示增量備份檔中的內容,結合使用 -t與 -g 或 -G。若要顯示較詳細的資訊,可再加上二個--verbose參數,例:
$ tar tvvf archive2.tar -G
多重卷冊
現在一般較少使用多重卷冊multi-volume功能了。一些較流行常見的壓縮軟體多半都有這項功能,在過去磁碟片盛行時期,可用此功能把較大的檔案壓縮並存到多張磁碟片中。隨著儲存裝置的價格下降與容量大增,以及網路傳輸頻寬的大幅擴大以及傳輸品質穩定化,較少有這種把大檔案壓縮並分割以方便儲存或以網路傳輸的需要。無論如何,這種功能還是會繼續存在,tar也有這功能,可用在磁帶機,或是一般儲存裝置,與此較相關的重要選項有:- -M, --multi-volume:建立/列示/解開時,指定使用多重卷冊。
- -L, --tape-length=N:指定磁帶長度,即容量,如20M,或2G,分別表20 MB與2 GB。如果數字後無後置字母,預設的容量單位為1024 bytes,也就是MB。
$ tar cf /dev/tape -M folder_to_archive/
tar在偵測到達磁帶尾端的方法並不是很靠譜,在某些作業系統或裝置上會出錯。此時可以用 -L 選項讓tar知道磁帶的容量,此選項也會自動選擇 -M 選項。例如磁帶容量是4 GB:
$ tar cf /dev/tape -L 4G folder_to_archive/
或是:
$ tar cf /dev/tape -L 41943040 folder_to_archive/
第一個磁帶寫滿時會出現提示文字,要你準備好卷冊 #2,也就是第二個磁帶。可在此提示中輸入 ? 查看進一步說明。記得只有在更換好磁帶之後才按 y 繼續備份動作,不然可能會寫到尚未換掉的第一個磁帶中。如果備份到檔案,採用上述方式時,則是要在提示中輸入 n 第2卷冊檔案名稱,例如
n archive2.tar
,然後按Enter鍵繼續。若卷冊較多時,這顯然不很方便,此時可利用Bash的Brace Expansion展開的功能,指定多個卷冊檔案,如:
$ tar c --file=archive_{00..10}.tar -L 10M folder_to_archive/
上行會產生archive_00.tar到archive_10.tar的檔名,而實際上可能只會用到06。這數量可事先估計一下,例如估計在100之內,也可改成像{000..100}。另外要注意一點,所要封存檔案的檔名若太長,無法寫到多重卷冊標頭之中,會被截斷,並且會出現警示文字,不過自己實測後並無發現不良影響。以上例的備份而言,若要還原解開到另一目錄folder2:
$ tar x --file=archive_{00..10}.tar -M -C folder2/
注意上行因為不需要指定容量大小,所以改用 -M 而不是 -L 。以上只是多重卷冊方面較簡單的說明,較詳細的資訊可見[5]。[6]則提到另一種做法是配合split做檔案分割,如:
$ tar czvf - folder_to_archive/ | split -d -b 10M archive.tar.gz._
這樣分割出來的檔案群會像 archive.tar.gz._00, archive.tar.gz._01, ... archive.tar.gz._06 解開還原的方式則是:
$ cat archive.tar.gz._* | tar xzvf - -C folder2/
複製目錄並保留屬性
有時想從某處複製整個目錄,並且想保留目錄或檔案的原有屬性都不變動,像時間戳記,除了使用 rsync 指令:
$ rsync -av folder1 folder2
也可利用tar的封存、解開的功能:
$ tar cf- source-dir/ | tar xf- -C target-parent-dir/
上例中的 - 代表著stdout/stdio,因 -f- 是預設(見 tar --show-defaults
),所以可省略:
$ tar c source-dir/ | tar x -C target-parent-dir/
沒有留言:
張貼留言