tar
tape archives,用來打包檔案,檔案格式具備可攜性
打包(或者叫歸檔,因為不壓縮):
# -c 建立檔案,-f 指定檔案名稱
tar -cf bundle.tar file1 file2...
# 支援萬用字元
tar -cf bash_bundle.tar "*.sh"
追加:
# -r 向已存在的包中添加一個檔案
tar -rf bash_bundle.tar new.sh
# 對比時間戳記,比同名檔案新的話才添加
# vv 是為了輸出詳細日誌,沒有就表示檔案不新,沒往進塞
tar -uvvf bash_bundle.tar new.sh
刪除:
# --delete 刪除包裡的檔案
tar -f sh.tar --delete test.sh
P.S. Mac 下沒有 --delete 選項
查看:
# -t 查看包內容
tar -tf bash_bundle.tar
# -v 看詳細點的(檔案權限、修改日期,類似於 ls -l)
tar -tvf bash_bundle.tar
# -vv 看更詳細的(比上面多一行包檔案格式資訊)
tar -tvvf bash_bundle.tar
P.S. -v 和 -vv 可以配合其他選項,用來輸出 log
提取(解壓縮):
# -x 提取到目前目錄
tar -xf bash_bundle.tar
# -C 提取到指定目錄(目錄必須已存在,否則報錯)
tar -xf bash_bundle.tar -C ./tmp
# 只提取指定檔案
tar -C ./tmp -xf bash_bundle.tar ab.diff
奇怪的技巧:
# stdin/stdout
# 把打包結果輸出到 stdout
tar -cf - test.sh
# 從 stdin 讀取包內容
tar -xf - -C ./tmp test.sh
配合 ssh,就能一管子插到遠端機器上,批次傳輸檔案:
# 本地打包,遠端提取(用來同步目錄)
tar -cf - test.sh | ssh <user>@<IP> "mkdir -p ~/tmp/sh; tar -xf - -C ~/tmp/sh"
# 本地打包,遠端保存(用來批次上傳檔案)
tar -cf - test.sh | ssh jiajiejie.jj@10.125.1.214 "mkdir -p ~/tmp; cat > ~/tmp/sh.tar"
# 把遠端檔案提取到本地(用來批次下載檔案)
ssh jiajiejie.jj@10.125.1.214 "cat ~/tmp/sh.tar" | tar -xf - -C ./tmp
減少中間檔案,減少讀寫磁碟,效率更高一些
tar 預設只是歸檔,用來打包檔案,不壓縮,提供了壓縮選項:
# -z 壓縮為 zip 格式
tar -a -cf bash.tar.gz "*.sh"
# -j 壓縮為 bunzip2 格式
tar -a -cf bash.tar.bz2 "*.sh"
# --lzma 壓縮為 lzma 格式(Mac 下沒有該選項)
tar -a -cf bash.tar.lzma
tar -a -cf filename.tar.lzo
-a/--autocompress 選項能夠根據檔案名稱自動選擇壓縮格式,如上例。解壓縮時需要指定壓縮格式,如常見的編譯安裝方法:
# 下載源碼
wget http://path/to/source.tar.gz
# 解壓縮
tar -zxvf source.tar.gz
# 或者,-a 自動檢測壓縮格式
tar -axvf source.tar.gz
# 三板斧
cd source
./configure
make
make install
其他選項和用法:
# -A 合併包(把 2 合併到 1)
tar -Af bundle1.tar bundle2.tar
# -d 比較包裡外的檔案
tar -df sh1.tar test.sh
# --exclude 排除指定檔案(排除 md 檔案)
tar -cf bundle.tar "*" --exclude "*.md"
# 或者把需要排除的檔案名稱寫入檔案,透過 -X 選項排除
echo "*.md" > tar.ignore
tar -cf bundle.tar "*" -X tar.ignore
# 排除版本控制目錄(.git, .svn 之類的)
tar --exclude-vcs -zcvf proj.tar.gz ./proj
# --totals 輸出包檔案大小
tar -zcvf dir.tar.gz "*" --totals
P.S. Mac 下沒有 -d、--totals 選項,低版本 tar 不支援 --exclude-vcs
cpio
與 tar 類似,從 stdin 接收輸入檔案名稱,並把打包檔案輸出到 stdout,多用於 rpm 軟體包,不常用
特點是支援絕對路徑: tar 打包時會把絕對路徑轉相對路徑, cpio 不轉,如果打包時輸入了絕對路徑,提取時也按絕對路徑恢復,否則,與 tar 一樣,提取到目前目錄:
# 只能從 stdin 接收檔案名稱
# 打包,-o 指定輸出檔案名稱,-v 輸出檔案列表
find . -name "*.sh" -print | cpio -ov > bash.cpio
# 查看,-i 指定輸入包名,-t 列出包內容
cpio -vit < bundle.cpio
# 提取,-d 表示提取操作
cpio -vid < bundle.cpio
注意: cpio 覆蓋檔案沒有提示,如果絕對路徑對應的檔案已存在且比較舊,會被靜默替換掉。提取時會自動對比時間戳記,如果包裡檔案新,就替掉,否則跳過提取該檔案
P.S. 用 cpio 解壓縮 rpm 包需要先把 rpm 包轉成 cpio 包,需要 rpm2cpio 工具
gzip/gunzip、zcat
這 3 個命令都能處理 gzip 壓縮檔案, gzip 命令只能壓縮單檔案,無法直接處理目錄和多個檔案。所以一般先用 tar 命令打包,再用 gzip 壓縮
gzip/gunzip
壓縮:
# 會刪除 test.sh,再生成 test.sh.gz
gzip test.sh
解壓縮:
# 刪除 test.sh.gz,生成 test.sh
gunzip test.sh.gz
查看:
# -l 列出包內檔案名稱、壓縮前後大小、壓縮比
gzip -l test.sh.gz
也配合 stdin/stdout 使用:
# -c 輸出到 stdout
cat sub.sh | gzip -c > sub.sh.gz
這樣就保留了原檔案 sub.sh
其他選項和用法:
# --fast/--best 指定壓縮級別,分別對應最低/最高壓縮比
# 一共有 9 級,--fast 對應 1,--best 對應 9
gzip test.sh --fast
# 等價於
gzip test.sh -1
# tar 的 -z 選項使用 gzip 壓縮
tar -zcvf bash.tar.gz "*.sh"
# 或者,-a 自動檢測壓縮格式
tar -acvf bash.tar.gz "*.sh"
# 或者,先打包再壓縮
tar -cvf bash.tar "*.sh"; gzip bash.tar
zcat
不解壓縮,直接讀取 gzip 壓縮檔案內容,輸出到 stdout :
# 讀取 gz 檔案內容
zcat test.sh.gz
P.S. 在 Mac 下 zcat 會強制給輸入檔案名稱添上 .Z 後綴,導致報錯:
zcat: can't stat: sub.sh.gz (sub.sh.gz.Z): No such file or directory
所以為了保證可攜性,不建議用 zcat ,可以用 gunzip -c 代替,更多資訊請查看 zcat on OS X always appends a .Z to the filename (better use gunzip -c)
bzip2/bunzip2
一般情況下,比 gzip 壓縮比更高,用法與 gzip 完全一致:
# 壓縮
# 會刪除 test.sh,生成 test.sh.bz2
bzip2 test.sh
# 解壓縮
bunzip2 test.sh.bz2
實測發現對於文字檔案 test.sh ,同樣火力全開( -9 )的情況下, bzip2 比 gzip 的壓縮比還稍低一點:
-rwxr-xr-x 1 ayqy staff 1064 4 9 16:31 test.sh
-rwxr-xr-x 1 ayqy staff 682 4 9 16:31 test.sh.bz2
-rwxr-xr-x 1 ayqy staff 632 4 9 16:31 test.sh.gz
同樣, gzip 有的 bzip2 幾乎都有:
# 指定壓縮級別
bzip2 -1 test.sh
# tar -j 選項壓縮成 bz2
tar -jcvf bash.tar.gz "*.sh"
# ...同 gzip
另外,還有一些獨有特性( bzip2 有,而 gzip 沒有的):
# -k 保留輸入檔案
bzip2 -k test.sh
P.S. 還有一個新一些的壓縮工具叫 lzma/unlzma ,據說壓縮比更高,一般不給預裝,需要手動裝一個,用法與 gzip/bzip2 一樣,二者的所有選項都支援
zip
非常常見的壓縮格式,壓縮比不很高,但很多網路資源都是這個格式
壓縮:
# 生成 test.sh.zip,不刪除 test.sh
zip test.sh.zip test.sh
# -r 遞迴處理目錄
zip -r bundle.zip .
解壓縮:
# 解壓縮到目前目錄,不會刪除 test.sh.zip
unzip test.sh.zip
如果發現目標檔案已存在,會提示選項是否替換/重新命名/取消
更新:
# -u 用新檔案替掉包裡的
zip test.sh.zip -u test.sh
刪除:
# -d 刪除包裡指定檔案
zip -d test.sh.zip test.sh
查看:
# -l 列出包內容
unzip -l test.sh.zip
加密/編碼
linux 提供了很多加密/編碼工具: crypt , gpg , base64 等等
crypt
從 stdin 接收檔案輸入和口令,把加密結果輸出到 stdout
加密:
# 互動提示輸入口令
crypt < test.sh
# 把加密結果重新導向到檔案
crypt < test.sh > test.lock.sh
解密:
# 同樣,只接受來自 stdin 的,只輸出到 stdout
crypt 口令 < test.lock.sh > test.sh
P.S. Mac 下沒有該命令
gpg
GUN privacy guard ,採用金鑰簽名方式,簡單用法如下:
# 加密,互動提示輸入口令,生成 test.sh.gpg
gpg -c test.sh
# 解密,互動提示輸入口令,生成 test.sh.gpg
gpg test.sh.gpg
P.S. Mac 下沒有該命令
base64
與上面 2 個命令不同,因為很容易解碼,與明文沒什麼區別,只能算作編碼方式:
# 編碼
base64 test.sh > test.sh.base64
# 解碼
base64 -D test.sh.base64 > test.sh
rsync
rsync 用來備份系統快照,自帶 diff 和壓縮機制,比 scp 等命令高效,此外還支援網路數據傳輸,會比較源和目標端的檔案,只複製備份更新的,也支援加密選項
備份:
# 備份到本地
# 在目前目錄建立 bash.bak/bash,複製下面所有內容
# -a 歸檔,-v 輸出 log
rsync -av bash bash.bak
# 備份到遠端
rsync -av bash ayqy@<IP>:~/bak
注意:路徑格式有講究,如果源路徑結尾有 / ,就只複製下面所有檔案/子檔案到目標路徑,否則在目標路徑下建立對應資料夾,再複製下面所有檔案/子檔案。一句話,有 / 不建立資料夾,目標路徑結尾的 / 含義類似
定期備份只需要定期執行相同的命令,自動檢查差異和更新並備份
恢復:
# 從本地恢復
rsync -av bash.bak bash
# 從遠端恢復
rsync -av ayqy@<IP>:~/bak bash
交換參數位置即可
其他選項和特性:
# -z 壓縮傳輸
rsync -zav bash bash.bak
# --exclude 排除指定檔案
rsync -av bash bash.bak --exclude "*.md"
# --delete 備份時刪除不存在的檔案,預設不會刪掉源端已經刪掉的東西
rsync -av bash bash.bak --exclude --delete
暫無評論,快來發表你的看法吧