Linux私房菜第八章

一:

Linux 系統常見的壓縮指令

在Linux的環境中,壓縮檔案的副檔名大多是:『*.tar, *.tar.gz, *.tgz, *.gz, *.Z, *.bz2, *.xz』,為什麼會有這樣的副檔名呢?不是說 Linux 的副檔名沒有什麼作用嗎?

這是因為 Linux 支援的壓縮指令非常多,且不同的指令所用的壓縮技術並不相同,當然彼此之間可能就無法互通壓縮/解壓縮檔案囉。 所以,當你下載到某個壓縮檔時,自然就需要知道該檔案是由哪種壓縮指令所製作出來的,好用來對照著解壓縮啊! 也就是說,雖然 Linux 檔案的屬性基本上是與檔名沒有絕對關係的, 但是為了幫助我們人類小小的腦袋瓜子,所以適當的副檔名還是必要的! 底下我們就列出幾個常見的壓縮檔案副檔名吧:

*.Z         compress 程式壓縮的檔案;
*.zip       zip 程式壓縮的檔案;
*.gz        gzip 程式壓縮的檔案;
*.bz2       bzip2 程式壓縮的檔案;
*.xz        xz 程式壓縮的檔案;
*.tar       tar 程式打包的資料,並沒有壓縮過;
*.tar.gz    tar 程式打包的檔案,其中並且經過 gzip 的壓縮
*.tar.bz2   tar 程式打包的檔案,其中並且經過 bzip2 的壓縮
*.tar.xz    tar 程式打包的檔案,其中並且經過 xz 的壓縮

Linux上常見的壓縮指令就是 gzip, bzip2 以及最新的 xz ,至於 compress 已經退流行了。為了支援 windows 常見的 zip,其實 Linux 也早就有 zip 指令了! gzip 是由 GNU 計畫所開發出來的壓縮指令,該指令已經取代了 compress 。 後來 GNU 又開發出 bzip2 及 xz 這幾個壓縮比更好的壓縮指令!不過,這些指令通常僅能針對一個檔案來壓縮與解壓縮,如此一來, 每次壓縮與解壓縮都要一大堆檔案,豈不煩人?此時,那個所謂的『打包軟體, tar』就顯的很重要啦!

這個 tar 可以將很多檔案『打包』成為一個檔案!甚至是目錄也可以這麼玩。不過,單純的 tar 功能僅是『打包』而已,亦即是將很多檔案集結成為一個檔案, 事實上,他並沒有提供壓縮的功能,後來,GNU 計畫中,將整個 tar 與壓縮的功能結合在一起,如此一來提供使用者更方便並且更強大的壓縮與打包功能! 底下我們就來談一談這些在 Linux 底下基本的壓縮指令吧!


二:

gzip, zcat/zmore/zless/zgrep

gzip 可以說是應用度最廣的壓縮指令了!目前 gzip 可以解開 compress, zip 與 gzip 等軟體所壓縮的檔案。 至於 gzip 所建立的壓縮檔為 *.gz 的檔名喔!讓我們來看看這個指令的語法吧:

[dmtsai@study ~]$ gzip [-cdtv#] 檔名
[dmtsai@study ~]$ zcat 檔名.gz
選項與參數:
-c  :將壓縮的資料輸出到螢幕上,可透過資料流重導向來處理;
-d  :解壓縮的參數;
-t  :可以用來檢驗一個壓縮檔的一致性~看看檔案有無錯誤;
-v  :可以顯示出原檔案/壓縮檔案的壓縮比等資訊;
-#  :# 為數字的意思,代表壓縮等級,-1 最快,但是壓縮比最差、-9 最慢,但是壓縮比最好!預設是 -6

範例一:找出 /etc 底下 (不含子目錄) 容量最大的檔案,並將它複製到 /tmp ,然後以 gzip 壓縮
[dmtsai@study ~]$ ls -ldSr /etc/*   # 忘記選項意義?請自行 man 囉!
.....(前面省略).....
-rw-r--r--.  1 root root    25213 Jun 10  2014 /etc/dnsmasq.conf
-rw-r--r--.  1 root root    69768 May  4 17:55 /etc/ld.so.cache
-rw-r--r--.  1 root root   670293 Jun  7  2013 /etc/services

[dmtsai@study ~]$ cd /tmp 
[dmtsai@study tmp]$ cp /etc/services .
[dmtsai@study tmp]$ gzip -v services
services:        79.7% -- replaced with services.gz
[dmtsai@study tmp]$ ll /etc/services /tmp/services*
-rw-r--r--. 1 root   root   670293 Jun  7  2013 /etc/services
-rw-r--r--. 1 dmtsai dmtsai 136088 Jun 30 18:40 /tmp/services.gz

當你使用 gzip 進行壓縮時,在預設的狀態下原本的檔案會被壓縮成為 .gz 的檔名,原始檔案就不再存在了。 這點與一般習慣使用 windows 做壓縮的朋友所熟悉的情況不同喔!要注意!要注意! 此外,使用 gzip 壓縮的檔案在 Windows 系統中,竟然可以被 WinRAR/7zip 這個軟體解壓縮呢!很好用吧!至於其他的用法如下:

範例二:由於 services 是文字檔,請將範例一的壓縮檔的內容讀出來!
[dmtsai@study tmp]$ zcat services.gz
# 由於 services 這個原本的檔案是是文字檔,因此我們可以嘗試使用 zcat/zmore/zless 去讀取!
# 此時螢幕上會顯示 servcies.gz 解壓縮之後的原始檔案內容!

範例三:將範例一的檔案解壓縮
[dmtsai@study tmp]$ gzip -d services.gz
# 鳥哥不要使用 gunzip 這個指令,不好背!使用 gzip -d 來進行解壓縮!
# 與 gzip 相反, gzip -d 會將原本的 .gz 刪除,回復到原本的 services 檔案。

範例四:將範例三解開的 services 用最佳的壓縮比壓縮,並保留原本的檔案
[dmtsai@study tmp]$ gzip -9 -c services > services.gz

範例五:由範例四再次建立的 services.gz 中,找出 http 這個關鍵字在哪幾行?
[dmtsai@study tmp]$ zgrep -n 'http' services.gz
14:#       http://www.iana.org/assignments/port-numbers
89:http            80/tcp          www www-http    # WorldWideWeb HTTP
90:http            80/udp          www www-http    # HyperText Transfer Protocol
.....(底下省略).....

其實 gzip 的壓縮已經最佳化過了,所以雖然 gzip 提供 1~9 的壓縮等級,不過使用預設的 6 就非常好用了! 因此上述的範例四可以不要加入那個 -9 的選項。範例四的重點在那個 -c 與 > 的使用囉!-c 可以將原本要轉成壓縮檔的資料內容,將它變成文字類型從螢幕輸出, 然後我們可以透過大於 (>) 這個符號,將原本應該由螢幕輸出的資料,轉成輸出到檔案而不是螢幕,所以就能夠建立出壓縮擋了。只是檔名也要自己寫, 當然最好還是遵循 gzip 的壓縮檔名要求較佳喔!!更多的 > 這個符號的應用,我們會在 bash 章節再次提及!

cat/more/less 可以使用不同的方式來讀取純文字檔,那個 zcat/zmore/zless 則可以對應於 cat/more/less 的方式來讀取純文字檔被壓縮後的壓縮檔! 由於 gzip 這個壓縮指令主要想要用來取代 compress 的,所以不但 compress 的壓縮檔案可以使用 gzip 來解開,同時 zcat 這個指令可以同時讀取 compress 與 gzip 的壓縮檔呦!

另外,如果你還想要從文字壓縮檔當中找資料的話,可以透過 zgrep 來搜尋關鍵字喔!而不需要將壓縮檔解開才以 grep 進行! 這對查詢備份中的文字檔資料相當有用!


三:

bzip2, bzcat/bzmore/bzless/bzgrep

若說 gzip 是為了取代 compress 並提供更好的壓縮比而成立的,那麼 bzip2 則是為了取代 gzip 並提供更佳的壓縮比而來的。 bzip2 真是很不錯用的東西~這玩意的壓縮比竟然比 gzip 還要好~至於 bzip2 的用法幾乎與 gzip 相同!看看底下的用法吧!

[dmtsai@study ~]$ bzip2 [-cdkzv#] 檔名
[dmtsai@study ~]$ bzcat 檔名.bz2
選項與參數:
-c  :將壓縮的過程產生的資料輸出到螢幕上!
-d  :解壓縮的參數
-k  :保留原始檔案,而不會刪除原始的檔案喔!
-z  :壓縮的參數 (預設值,可以不加)
-v  :可以顯示出原檔案/壓縮檔案的壓縮比等資訊;
-#  :與 gzip 同樣的,都是在計算壓縮比的參數, -9 最佳, -1 最快!

範例一:將剛剛 gzip 範例留下來的 /tmp/services 以 bzip2 壓縮
[dmtsai@study tmp]$ bzip2 -v services
  services:  5.409:1,  1.479 bits/byte, 81.51% saved, 670293 in, 123932 out.
[dmtsai@study tmp]$ ls -l services*
-rw-r--r--. 1 dmtsai dmtsai 123932 Jun 30 18:40 services.bz2
-rw-rw-r--. 1 dmtsai dmtsai 135489 Jun 30 18:46 services.gz
# 此時 services 會變成 services.bz2 之外,你也可以發現 bzip2 的壓縮比要較 gzip 好喔!!
# 壓縮率由 gzip 的 79% 提升到 bzip2 的 81% 哩!

範例二:將範例一的檔案內容讀出來!
[dmtsai@study tmp]$ bzcat services.bz2

範例三:將範例一的檔案解壓縮
[dmtsai@study tmp]$ bzip2 -d services.bz2

範例四:將範例三解開的 services 用最佳的壓縮比壓縮,並保留原本的檔案
[dmtsai@study tmp]$ bzip2 -9 -c services > services.bz2

看上面的範例,你會發現到 bzip2 連選項與參數都跟 gzip 一模一樣!只是副檔名由 .gz 變成 .bz2 而已!其他的用法都大同小異,所以鳥哥就不一一介紹了! 你也可以發現到 bzip2 的壓縮率確實比 gzip 要好些!不過,對於大容量檔案來說,bzip2 壓縮時間會花比較久喔!至少比 gzip 要久的多! 這沒辦法~要有更多可用容量,就得要花費相對應的時間!還 OK 啊!


四:

xz, xzcat/xzmore/xzless/xzgrep

雖然 bzip2 已經具有很棒的壓縮比,不過顯然某些自由軟體開發者還不滿足,因此後來還推出了 xz 這個壓縮比更高的軟體!這個軟體的用法也跟 gzip/bzip2 幾乎一模一樣! 那我們就來瞧一瞧!

[dmtsai@study ~]$ xz [-dtlkc#] 檔名
[dmtsai@study ~]$ xcat 檔名.xz
選項與參數:
-d  :就是解壓縮啊!
-t  :測試壓縮檔的完整性,看有沒有錯誤
-l  :列出壓縮檔的相關資訊
-k  :保留原本的檔案不刪除~
-c  :同樣的,就是將資料由螢幕上輸出的意思!
-#  :同樣的,也有較佳的壓縮比的意思!

範例一:將剛剛由 bzip2 所遺留下來的 /tmp/services 透過 xz 來壓縮!
[dmtsai@study tmp]$ xz -v services
services (1/1)
  100 %        97.3 KiB / 654.6 KiB = 0.149

[dmtsai@study tmp]$ ls -l services*
-rw-rw-r--. 1 dmtsai dmtsai 123932 Jun 30 19:09 services.bz2
-rw-rw-r--. 1 dmtsai dmtsai 135489 Jun 30 18:46 services.gz
-rw-r--r--. 1 dmtsai dmtsai  99608 Jun 30 18:40 services.xz
# 各位觀眾!看到沒有啊!!容量又進一步下降的更多耶!好棒的壓縮比!

範例二:列出這個壓縮檔的資訊,然後讀出這個壓縮檔的內容
[dmtsai@study tmp]$ xz -l services.xz
Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename
    1       1     97.3 KiB    654.6 KiB  0.149  CRC64   services.xz
# 竟然可以列出這個檔案的壓縮前後的容量,真是太人性化了!這樣觀察就方便多了!

[dmtsai@study tmp]$ xzcat services.xz

範例三:將他解壓縮吧!
[dmtsai@study tmp]$ xz -d services.xz

範例四:保留原檔案的檔名,並且建立壓縮檔!
[dmtsai@study tmp]$ xz -k services

雖然 xz 這個壓縮比真的好太多太多了!以鳥哥選擇的這個 services 檔案為範例,他可以將 gzip 壓縮比 (壓縮後/壓縮前) 的 21% 更進一步優化到 15% 耶! 差非常非常多!不過, xz 最大的問題是...時間花太久了!如果你曾經使用過 xz 的話,應該會有發現,他的運算時間真的比 gzip 久很多喔!

鳥哥以自己的系統,透過『 time [gzip|bzip2|xz] -c services > services.[gz|bz2|xz] 』去執行運算結果,結果發現這三個指令的執行時間依序是: 0.019s, 0.042s, 0.261s, 看最後一個數字!差了 10 倍的時間耶!所以,如果你並不覺得時間是你的成本考量,那麼使用 xz 會比較好!如果時間是你的重要成本,那麼 gzip 恐怕是比較適合的壓縮軟體喔!


五:

打包指令: tar

前一小節談到的指令大多僅能針對單一檔案來進行壓縮,雖然 gzip, bzip2, xz 也能夠針對目錄來進行壓縮,不過, 這兩個指令對目錄的壓縮指的是『將目錄內的所有檔案 "分別" 進行壓縮』的動作!而不像在 Windows 的系統,可以使用類似 WinRAR 這一類的壓縮軟體來將好多資料『包成一個檔案』的樣式。

這種將多個檔案或目錄包成一個大檔案的指令功能,我們可以稱呼他是一種『打包指令』啦! 那 Linux 有沒有這種打包指令呢?是有的!那就是鼎鼎大名的 tar 這個玩意兒了! tar 可以將多個目錄或檔案打包成一個大檔案,同時還可以透過 gzip/bzip2/xz 的支援,將該檔案同時進行壓縮! 更有趣的是,由於 tar 的使用太廣泛了,目前 Windows 的 WinRAR 也支援 .tar.gz 檔名的解壓縮呢! 很不錯吧!所以底下我們就來玩一玩這個咚咚!

Top

8.3.1 tar

tar 的選項與參數非常的多!我們只講幾個常用的選項,更多選項您可以自行 man tar 查詢囉!

[dmtsai@study ~]$ tar [-z|-j|-J] [cv] [-f 待建立的新檔名] filename... <==打包與壓縮
[dmtsai@study ~]$ tar [-z|-j|-J] [tv] [-f 既有的 tar檔名]             <==察看檔名
[dmtsai@study ~]$ tar [-z|-j|-J] [xv] [-f 既有的 tar檔名] [-C 目錄]   <==解壓縮
選項與參數:
-c  :建立打包檔案,可搭配 -v 來察看過程中被打包的檔名(filename)
-t  :察看打包檔案的內容含有哪些檔名,重點在察看『檔名』就是了;
-x  :解打包或解壓縮的功能,可以搭配 -C (大寫) 在特定目錄解開
      特別留意的是, -c, -t, -x 不可同時出現在一串指令列中。
-z  :透過 gzip  的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.gz
-j  :透過 bzip2 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.bz2
-J  :透過 xz    的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.xz
      特別留意, -z, -j, -J 不可以同時出現在一串指令列中
-v  :在壓縮/解壓縮的過程中,將正在處理的檔名顯示出來!
-f filename:-f 後面要立刻接要被處理的檔名!建議 -f 單獨寫一個選項囉!(比較不會忘記)
-C 目錄    :這個選項用在解壓縮,若要在特定目錄解壓縮,可以使用這個選項。

其他後續練習會使用到的選項介紹:
-p(小寫) :保留備份資料的原本權限與屬性,常用於備份(-c)重要的設定檔
-P(大寫) :保留絕對路徑,亦即允許備份資料中含有根目錄存在之意;
--exclude=FILE:在壓縮的過程中,不要將 FILE 打包! 

其實最簡單的使用 tar 就只要記憶底下的方式即可:

  • 壓 縮:tar -jcv -f filename.tar.bz2 要被壓縮的檔案或目錄名稱
  • 查 詢:tar -jtv -f filename.tar.bz2
  • 解壓縮:tar -jxv -f filename.tar.bz2 -C 欲解壓縮的目錄

那個 filename.tar.bz2 是我們自己取的檔名,tar 並不會主動的產生建立的檔名喔!我們要自訂啦! 所以副檔名就顯的很重要了!如果不加 [-z|-j|-J] 的話,檔名最好取為 *.tar 即可。如果是 -j 選項,代表有 bzip2 的支援,因此檔名最好就取為 *.tar.bz2 ,因為 bzip2 會產生 .bz2 的副檔名之故! 至於如果是加上了 -z 的 gzip 的支援,那檔名最好取為 *.tar.gz 喔!瞭解乎?

另外,由於『 -f filename 』是緊接在一起的,過去很多文章常會寫成『-jcvf filename』,這樣是對的, 但由於選項的順序理論上是可以變換的,所以很多讀者會誤認為『-jvfc filename』也可以~事實上這樣會導致產生的檔名變成 c ! 因為 -fc 嘛!所以囉,建議您在學習 tar 時,將『 -f filename 』與其他選項獨立出來,會比較不容易發生問題。

閒話少說,讓我們來測試幾個常用的 tar 方法吧!

  • 使用 tar 加入 -z, -j 或 -J 的參數備份 /etc/ 目錄

有事沒事備份一下 /etc 這個目錄是件好事!備份 /etc 最簡單的方法就是使用 tar 囉!讓我們來玩玩先:

[dmtsai@study ~]$ su -  # 因為備份 /etc 需要 root 的權限,否則會出現一堆錯誤
[root@study ~]# time tar -zpcv -f /root/etc.tar.gz /etc
tar: Removing leading `/' from member names  <==注意這個警告訊息
/etc/
....(中間省略)....
/etc/hostname
/etc/aliases.db

real    0m0.799s   # 多了 time 會顯示程式運作的時間!看 real 就好了!花去了 0.799s
user    0m0.767s
sys     0m0.046s
# 由於加上 -v 這個選項,因此正在作用中的檔名就會顯示在螢幕上。
# 如果你可以翻到第一頁,會發現出現上面的錯誤訊息!底下會講解。
# 至於 -p 的選項,重點在於『保留原本檔案的權限與屬性』之意。

[root@study ~]# time tar -jpcv -f /root/etc.tar.bz2 /etc
....(前面省略)....
real    0m1.913s
user    0m1.881s
sys     0m0.038s
[root@study ~]# time tar -Jpcv -f /root/etc.tar.xz  /etc
....(前面省略)....
real    0m9.023s
user    0m8.984s
sys     0m0.086s
# 顯示的訊息會跟上面一模一樣囉!不過時間會花比較多!使用了 -J 時,會花更多時間

[root@study ~]# ll /root/etc*
-rw-r--r--. 1 root root 6721809 Jul  1 00:16 /root/etc.tar.bz2
-rw-r--r--. 1 root root 7758826 Jul  1 00:14 /root/etc.tar.gz
-rw-r--r--. 1 root root 5511500 Jul  1 00:16 /root/etc.tar.xz
[root@study ~]# du -sm /etc
28     /etc  # 實際目錄約佔有 28MB 的意思!

壓縮比越好當然要花費的運算時間越多!我們從上面可以看到,雖然使用 gzip 的速度相當快,總時間花費不到 1 秒鐘,但是壓縮率最糟糕! 如果使用 xz 的話,雖然壓縮比最佳!不過竟然花了 9 秒鐘的時間耶!這還僅是備份 28MBytes 的 /etc 而已,如果備份的資料是很大容量的, 那你真的要考量時間成本才行!

至於加上『 -p 』這個選項的原因是為了保存原本檔案的權限與屬性!我們曾在第六章的 cp 指令介紹時談到權限與檔案類型(例如連結檔)對複製的不同影響。 同樣的,在備份重要的系統資料時,這些原本檔案的權限需要做完整的備份比較好。此時 -p 這個選項就派的上用場了。 接下來讓我們看看打包檔案內有什麼資料存在?

  • 查閱 tar 檔案的資料內容 (可察看檔名),與備份檔名有否根目錄的意義

要察看由 tar 所建立的打包檔案內部的檔名非常的簡單!可以這樣做:

[root@study ~]# tar -jtv -f /root/etc.tar.bz2
....(前面省略)....
-rw-r--r-- root/root       131 2015-05-25 17:48 etc/locale.conf
-rw-r--r-- root/root        19 2015-05-04 17:56 etc/hostname
-rw-r--r-- root/root     12288 2015-05-04 17:59 etc/aliases.db

如果加上 -v 這個選項時,詳細的檔案權限/屬性都會被列出來!如果只是想要知道檔名而已, 那麼就將 -v 拿掉即可。從上面的資料我們可以發現一件很有趣的事情,那就是每個檔名都沒了根目錄了!這也是上一個練習中出現的那個警告訊息『tar: Removing leading `/' from member names(移除了檔名開頭的 `/' )』所告知的情況!

那為什麼要拿掉根目錄呢?主要是為了安全!我們使用 tar 備份的資料可能會需要解壓縮回來使用, 在 tar 所記錄的檔名 (就是我們剛剛使用 tar -jtvf 所察看到的檔名) 那就是解壓縮後的實際檔名。 如果拿掉了根目錄,假設你將備份資料在 /tmp 解開,那麼解壓縮的檔名就會變成『/tmp/etc/xxx』。 但『如果沒有拿掉根目錄,解壓縮後的檔名就會是絕對路徑, 亦即解壓縮後的資料一定會被放置到 /etc/xxx 去!』如此一來,你的原本的 /etc/ 底下的資料, 就會被備份資料所覆蓋過去了!

Tips 鳥哥的圖示你會說:『既然是備份資料,那麼還原回來也沒有什麼問題吧?』想像一個狀況,你備份的資料是兩年前的舊版 CentOS 6.x, 你只是想要瞭解一下過去的備份內容究竟有哪些資料而已,結果一解開該檔案,卻發現你目前新版的 CentOS 7.x 底下的 /etc 被舊版的備份資料覆蓋了!此時你該如何是好?大概除了哭哭你也不能做啥事吧?所以囉,當然是拿掉根目錄比較安全一些的。

如果你確定你就是需要備份根目錄到 tar 的檔案中,那可以使用 -P (大寫) 這個選項,請看底下的例子分析:

範例:將檔名中的(根)目錄也備份下來,並察看一下備份檔的內容檔名
[root@study ~]# tar -jpPcv -f /root/etc.and.root.tar.bz2 /etc

[root@study ~]# tar -jtf /root/etc.and.root.tar.bz2
/etc/locale.conf
/etc/hostname
/etc/aliases.db
# 這次查閱檔名不含 -v 選項,所以僅有檔名而已!沒有詳細屬性/權限等參數。

有發現不同點了吧?如果加上 -P 選項,那麼檔名內的根目錄就會存在喔!不過,鳥哥個人建議,還是不要加上 -P 這個選項來備份! 畢竟很多時候,我們備份是為了要未來追蹤問題用的,倒不一定需要還原回原本的系統中! 所以拿掉根目錄後,備份資料的應用會比較有彈性!也比較安全呢!

  • 將備份的資料解壓縮,並考慮特定目錄的解壓縮動作 (-C 選項的應用)

那如果想要解打包呢?很簡單的動作就是直接進行解打包嘛!

[root@study ~]# tar -jxv -f /root/etc.tar.bz2
[root@study ~]# ll
....(前面省略)....
drwxr-xr-x. 131 root root    8192 Jun 26 22:14 etc
....(後面省略)....

此時該打包檔案會在『本目錄下進行解壓縮』的動作! 所以,你等一下就會在家目錄底下發現一個名為 etc 的目錄囉!所以囉,如果你想要將該檔案在 /tmp 底下解開, 可以 cd /tmp 後,再下達上述的指令即可。不過,這樣好像很麻煩呢~有沒有更簡單的方法可以『指定欲解開的目錄』呢? 有的,可以使用 -C 這個選項喔!舉例來說:

[root@study ~]# tar -jxv -f /root/etc.tar.bz2 -C /tmp
[root@study ~]# ll /tmp
....(前面省略)....
drwxr-xr-x. 131 root   root     8192 Jun 26 22:14 etc
....(後面省略)....

這樣一來,你就能夠將該檔案在不同的目錄解開囉!鳥哥個人是認為,這個 -C 的選項務必要記憶一下的! 好了,處理完畢後,請記得將這兩個目錄刪除一下呢!

[root@study ~]# rm -rf /root/etc /tmp/etc

再次強調,這個『 rm -rf 』是很危險的指令!下達時請務必要確認一下後面接的檔名。我們要刪除的是 /root/etc 與 /tmp/etc, 您可不要將 /etc/ 刪除掉了!系統會死掉的~ ^_^


六:

dd

我們在第七章當中的特殊 loop 裝置掛載時使用過 dd 這個指令對吧? 不過,這個指令可不只是製作一個檔案而已喔~這個 dd 指令最大的功效,鳥哥認為,應該是在於『備份』啊! 因為 dd 可以讀取磁碟裝置的內容(幾乎是直接讀取磁區"sector"),然後將整個裝置備份成一個檔案呢!真的是相當的好用啊~ dd 的用途有很多啦~但是我們僅講一些比較重要的選項,如下:

[root@study ~]# dd if="input_file" of="output_file" bs="block_size" count="number"
選項與參數:
if   :就是 input file 囉~也可以是裝置喔!
of   :就是 output file 喔~也可以是裝置;
bs   :規劃的一個 block 的大小,若未指定則預設是 512 bytes(一個 sector 的大小)
count:多少個 bs 的意思。

範例一:將 /etc/passwd 備份到 /tmp/passwd.back 當中
[root@study ~]# dd if=/etc/passwd of=/tmp/passwd.back
4+1 records in
4+1 records out
2092 bytes (2.1 kB) copied, 0.000111657 s, 18.7 MB/s
[root@study ~]# ll /etc/passwd /tmp/passwd.back
-rw-r--r--. 1 root root 2092 Jun 17 00:20 /etc/passwd
-rw-r--r--. 1 root root 2092 Jul  2 23:27 /tmp/passwd.back
# 仔細的看一下,我的 /etc/passwd 檔案大小為 2092 bytes,因為我沒有設定 bs ,
# 所以預設是 512 bytes 為一個單位,因此,上面那個 4+1 表示有 4 個完整的 512 bytes,
# 以及未滿 512 bytes 的另一個 block 的意思啦!事實上,感覺好像是 cp 這個指令啦~

範例二:將剛剛燒錄的光碟機的內容,再次的備份下來成為映像擋
[root@study ~]# dd if=/dev/sr0 of=/tmp/system.iso
177612+0 records in
177612+0 records out
90937344 bytes (91 MB) copied, 22.111 s, 4.1 MB/s
# 要將資料抓下來用這個方法,如果是要將映像檔寫入 USB 磁碟,就會變如下一個範例囉!

範例三:假設你的 USB 是 /dev/sda 好了,請將剛剛範例二的 image 燒錄到 USB 磁碟中
[root@study ~]# lsblk /dev/sda
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda    8:0    0   2G  0 disk             # 確實是 disk 而且有 2GB 喔!

[root@study ~]# dd if=/tmp/system.iso of=/dev/sda
[root@study ~]# mount /dev/sda /mnt
[root@study ~]# ll /mnt
dr-xr-xr-x. 131 root root 34816 Jun 26 22:14 etc
dr-xr-xr-x.   5 root root  2048 Jun 17 00:20 home
dr-xr-xr-x.   8 root root  4096 Jul  2 18:48 root
# 如果你不想要使用 DVD 來作為開機媒體,那可以將映像檔使用這個 dd 寫入 USB 磁碟,
# 該磁碟就會變成跟可開機光碟一樣的功能!可以讓你用 USB 來安裝 Linux 喔!速度快很多!

範例四:將你的 /boot 整個檔案系統透過 dd 備份下來
[root@study ~]# df -h /boot
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2      1014M  149M  866M  15% /boot       # 請注意!備份的容量會到 1G 喔!
[root@study ~]# dd if=/dev/vda2 of=/tmp/vda2.img
[root@study ~]# ll -h /tmp/vda2.img
-rw-r--r--. 1 root root 1.0G Jul  2 23:39 /tmp/vda2.img
# 等於是將整個 /dev/vda2 通通捉下來的意思~所以,檔案容量會跟整顆磁碟的最大量一樣大!

其實使用 dd 來備份是莫可奈何的情況,很笨耶!因為預設 dd 是一個一個磁區去讀/寫的,而且即使沒有用到的磁區也會倍寫入備份檔中! 因此這個檔案會變得跟原本的磁碟一模一樣大!不像使用 xfsdump 只備份檔案系統中有使用到的部份。不過, dd 就是因為不理會檔案系統, 單純有啥紀錄啥,因此不論該磁碟內的檔案系統你是否認識,它都可以備份、還原的!所以,鳥哥認為,上述的第三個案例是比較重要的學習喔!

例題:
你想要將你的 /dev/vda2 進行完整的複製到另一個 partition 上,請使用你的系統上面未分割完畢的容量再建立一個與 /dev/vda2 差不多大小的分割槽 (只能比 /dev/vda2 大,不能比他小!),然後將之進行完整的複製 (包括需要複製 boot sector 的區塊)。
答:
因為我們的 /dev/sda 也是個測試的 USB 磁碟,可以隨意惡搞!我們剛剛也才測試過將光碟映像檔給它複製進去而已。 現在,請你分割 /dev/sda1 出來,然後將 /dev/vda2 完整的拷貝進去 /dev/sda1 吧!
# 1. 先進行分割的動作
[root@study ~]# fdisk /dev/sda

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4195455, default 2048): Enter
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-4195455, default 4195455): Enter
Using default value 4195455
Partition 1 of type Linux and of size 2 GiB is set

Command (m for help): p
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048     4195455     2096704   83  Linux

Command (m for help): w

[root@study ~]# partprobe

# 2. 不需要格式化,直接進行 sector 表面的複製!
[root@study ~]# dd if=/dev/vda2 of=/dev/sda1
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 71.5395 s, 15.0 MB/s

[root@study ~]# xfs_repair -L /dev/sda1  # 一定要先清除一堆 log 才行!
[root@study ~]# uuidgen                  # 底下兩行在給予一個新的 UUID
896c38d1-bcb5-475f-83f1-172ab38c9a0c
[root@study ~]# xfs_admin -U 896c38d1-bcb5-475f-83f1-172ab38c9a0c /dev/sda1
# 因為 XFS 檔案系統主要使用 UUID 來分辨檔案系統,但我們使用 dd 複製,連 UUID
# 也都複製成為相同!當然就得要使用上述的 xfs_repair 及 xfs_admin 來修訂一下!

[root@study ~]# mount /dev/sda1 /mnt
[root@study ~]# df -h /boot /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2      1014M  149M  866M  15% /boot
/dev/sda1      1014M  149M  866M  15% /mnt
# 這兩個玩意兒會『一模一樣』喔!

# 3. 接下來!讓我們將檔案系統放大吧!!!
[root@study ~]# xfs_growfs /mnt
[root@study ~]# df -h /boot /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2      1014M  149M  866M  15% /boot
/dev/sda1       2.0G  149M  1.9G   8% /mnt

[root@study ~]# umount /mnt
非常有趣的範例吧!新分割出來的 partition 不需要經過格式化,因為 dd 可以將原本舊的 partition 上面,將 sector 表面的資料整個複製過來! 當然連同 superblock, boot sector, meta data 等等通通也會複製過來!是否很有趣呢?未來你想要建置兩顆一模一樣的磁碟時, 只要下達類似:  dd if=/dev/sda of=/dev/sdb ,就能夠讓兩顆磁碟一模一樣,甚至 /dev/sdb 不需要分割與格式化, 因為該指令可以將 /dev/sda 內的所有資料,包括 MBR 與 partition table 也複製到 /dev/sdb 說! ^_^

話說,用 dd 來處理這方面的事情真的是很方便,你也不需考量到啥有的沒的,通通是磁碟表面的複製而已!不過如果真的用在檔案系統上面, 例如上面這個案例,那麼再次掛載時,恐怕得要理解一下每種檔案系統的掛載要求!以上面的案例來說,你就得要先清除 XFS 檔案系統內的 log 之後, 重新給予一個跟原本不一樣的 UUID 後,才能夠順利掛載!同時,為了讓系統繼續利用後續沒有用到的磁碟空間,那個 xfs_growfs 就得要理解一下。 關於 xfs_growfs 我們會在後續第十四章繼續強調!這裡先理解即可。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值