跳到主要內容
黯羽輕揚每天積累一點點

常用簡單命令_bash 筆記 6

免費2017-04-09#Tool#linux备份#linux加密#zip与gzip#tar -zxvf

檔案搬運工

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 )的情況下, bzip2gzip 的壓縮比還稍低一點:

-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

評論

暫無評論,快來發表你的看法吧

提交評論