Linux檔案系統操作與磁碟管理
一、基本操作
1.1 檢視磁碟和目錄的容量
使用 df 命令檢視磁碟的容量
$ df
在實驗樓的環境中你將看到如下的輸出內容:
但在實際的物理主機上會更像這樣:
一般使用情況下,我們更多隻是關心第一行的內容也就是環境中的rootfs
或者物理主機上的/dev/sda2
"rootfs" : (Root File System)它是 Ramfs(Ramfs 是一個非常簡單的 Linux 檔案系統用於實現磁碟快取機制作為動態可調整大小的基於 ram 的檔案系統)或者 tmpfs 的一個特殊例項,它作為系統啟動時核心載入記憶體之後,在掛載真正的的磁碟之前的一個臨時檔案系統。通常的主機會在系統啟動後用磁碟上的檔案系統替換,只是在一些嵌入式系統中會只存在一個 rootfs ,或者像我們目前遇到的情況執行在虛擬環境中共享主機資源的系統也可能會採用這種方式。
物理主機上的 /dev/sda2 是對應著主機硬碟的分割槽,後面的數字表示分割槽號,數字前面的字母 a 表示第幾塊硬碟(也可能是可移動磁碟),你如果主機上有多塊硬碟則可能還會出現 /dev/sdb,/dev/sdc 這些磁碟裝置都會在 /dev 目錄下以檔案的存在形式。
接著你還會看到"1k-blocks"這個陌生的東西,它表示以磁碟塊大小的方式顯示容量,後面為相應的以塊大小表示的已用和可用容量,在你瞭解 Linux 的檔案系統之前這個就先不管吧,我們以一種你應該看得懂的方式展示:
$ df -h
現在你就可以使用命令檢視你主機磁碟的使用情況了。至於掛載點如果你還記得前面第 4 節介紹 Linux 目錄樹結構的內容,那麼你就應該能很好的理解掛載的概念,這裡就不再贅述。
使用 du 命令檢視目錄的容量
這個命令前面其實已經用了很多次了:
# 默認同樣以 blocks 的大小展示
$ du
# 加上`-h`引數,以更易讀的方式展示
$ du -h
-d
引數指定檢視目錄的深度
# 只檢視1級目錄的資訊
$ du -h -d 0 ~
# 檢視2級
$ du -h -d 1 ~
常用引數
du -h #同--human-readable 以K,M,G為單位,提高資訊的可讀性。
du -a #同--all 顯示目錄中所有檔案的大小。
du -s #同--summarize 僅顯示總計,只列出最後加總的值。
來自: http://man.linuxde.net/du
du
(estimate file space usage)命令與df
(report file system disk space usage)只用一字只差,首先就希望注意不要弄混淆了,以可以像我這樣從man手冊中獲取命令的完整描述,記全稱就不會搞混了。
二、簡單的磁碟管理
下面涉及的命令具有一定的危險性,操作不當可能會丟失你的個人資料,初學者建議在虛擬環境中進行操作
通常情況下,這一小節應該直接將如何掛載解除安裝磁碟,如何格式化磁碟,如何分割槽,但如你所見,我們的環境中沒東西給你掛,也沒東西給你格和分,所以首先我們會先建立一個虛擬磁碟來進行後續的練習操作
2.1 建立虛擬磁碟
dd
命令用於轉換和複製檔案,不過它的複製不同於cp
。之前提到過關於 Linux 的很重要的一點,一切即檔案,在 Linux 上,硬體的裝置驅動(如硬碟)和特殊裝置檔案(如/dev/zero
和/dev/random
)都像普通檔案一樣,只要在各自的驅動程式中實現了對應的功能,dd 也可以讀取自和/或寫入到這些檔案。這樣,dd
也可以用在備份硬體的引導扇區、獲取一定數量的隨機資料或者空資料等任務中。dd
程式也可以在複製時處理資料,例如轉換位元組序、或在
ASCII 與 EBCDIC 編碼間互換。
dd
的命令列語句與其他的 Linux 程式不同,因為它的命令列選項格式為選項=值
,而不是更標準的--選項 值
或-選項=值
。dd
預設從標準輸入中讀取,並寫入到標準輸出中,但可以用選項if
(input file,輸入檔案)和of
(output file,輸出檔案)改變。
我們先來試試用dd
命令從標準輸入讀入使用者輸入到標準輸出或者一個檔案:
# 輸出到檔案
$ dd of=test bs=10 count=1 # 或者 dd if=/dev/stdin of=test bs=10 count=1
# 輸出到標準輸出
$ dd if=/dev/stdin of=/dev/stdout bs=10 count=1
# 注
在打完了這個命令後,繼續在終端打字,作為你的輸入
上述命令從標準輸入裝置讀入使用者輸入(預設值,所以可省略)然後輸出到 test 檔案,bs
(block size)用於指定塊大小(預設單位為 Byte,也可為其指定如'K','M','G'等單位),count
用於指定塊數量。如上圖所示,我指定只讀取總共 10 個位元組的資料,當我輸入了“hello shiyanlou”之後加上空格回車總共 16 個位元組(一個英文字元佔一個位元組)內容,顯然超過了設定大小。使用和du
和cat
命令看到的寫入完成檔案實際內容確實只有
10 個位元組(那個黑底百分號表示這裡沒有換行符),而其他的多餘輸入將被擷取並保留在標準輸入。
前面說到dd
在拷貝的同時還可以實現資料轉換,那下面就舉一個簡單的例子:將輸出的英文字元轉換為大寫再寫入檔案:
$ dd if=/dev/stdin of=test bs=10 count=1 conv=ucase
你可以在man
文件中檢視其他所有轉換引數。
使用 dd 命令建立虛擬映象檔案
通過上面一小節,你應該掌握了dd
的基本使用,下面就來使用dd
命令來完成建立虛擬磁碟的第一步。
從/dev/zero
裝置建立一個容量為 256M 的空檔案:
$ dd if=/dev/zero of=virtual.img bs=1M count=256
$ du -h virtual.img
然後我們要將這個檔案格式化(寫入檔案系統),這裡我們要學到一個(準確的說是一組)新的命令來完成這個需求。
使用 mkfs 命令格式化磁碟(我們這裡是自己建立的虛擬磁碟映象)
你可以在命令列輸入 sudo mkfs
然後按下Tab
鍵,你可以看到很多個以 mkfs 為字首的命令,這些不同的字尾其實就是表示著不同的檔案系統,可以用 mkfs 格式化成的檔案系統。
我們可以簡單的使用下面的命令來將我們的虛擬磁碟映象格式化為ext4
檔案系統:
$ sudo mkfs.ext4 virtual.img
可以看到實際 mkfs.ext4 是使用 mke2fs 來完成格式化工作的。mke2fs 的引數很多,不過我們也不會經常格式化磁碟來玩,所以就掌握這基本用法吧,等你有特殊需求時,再檢視 man 文件解決。
更多關於檔案系統的知識,請檢視wiki:
如果你想想知道 Linux 支援哪些檔案系統你可以輸入ls -l /lib/modules/$(uname -r)/kernel/fs
(我們的環境中無法檢視)檢視。
使用 mount 命令掛載磁碟到目錄樹
使用者在 Linux/UNIX 的機器上開啟一個檔案以前,包含該檔案的檔案系統必須先進行掛載的動作,此時使用者要對該檔案系統執行 mount 的指令以進行掛載。通常是使用在 USB 或其他可移除儲存裝置上,而根目錄則需要始終保持掛載的狀態。又因為 Linux/UNIX 檔案系統可以對應一個檔案而不一定要是硬體裝置,所以可以掛載一個包含檔案系統的檔案到目錄樹。
Linux/UNIX 命令列的 mount 指令是告訴作業系統,對應的檔案系統已經準備好,可以使用了,而該檔案系統會對應到一個特定的點(稱為掛載點)。掛載好的檔案、目錄、裝置以及特殊檔案即可提供使用者使用。
我們先來使用mount
來檢視下主機已經掛載的檔案系統:
$ sudo mount
輸出的結果中每一行表示一個裝置或虛擬裝置,每一行最前面是裝置名,然後是 on 後面是掛載點,type 後面表示檔案系統型別,再後面是掛載選項(比如可以在掛載時設定以只讀方式掛載等等)。
那麼我們如何掛載真正的磁碟到目錄樹呢,mount
命令的一般格式如下:
mount [options] [source] [directory]
一些常用操作:
mount [-o [操作選項]] [-t 檔案系統型別] [-w|--rw|--ro] [檔案系統源] [掛載點]
我們現在直接來掛載我們建立的虛擬磁碟映象到/mnt
目錄:
$ mount -o loop -t ext4 virtual.img /mnt
# 也可以省略掛載型別,很多時候 mount 會自動識別
# 以只讀方式掛載
$ mount -o loop --ro virtual.img /mnt
# 或者mount -o loop,ro virtual.img /mnt
使用 umount 命令解除安裝已掛載磁碟
# 命令格式 sudo umount 已掛載裝置名或者掛載點,如:
$ sudo umount /mnt
不過遺憾的是,由於我們環境的問題(環境中使用的 Linux 核心在編譯時沒有新增對 Loop device的支援),所以你將無法掛載成功:
另外關於 loop 裝置,你可能會有諸多疑問,那麼請看下面來自維基百科/dev/loop的說明:
在類 UNIX 系統中,/dev/loop(或稱vnd (vnode disk)、lofi(迴圈檔案介面))是一種偽裝置,這種裝置使得檔案可以如同塊裝置一般被訪問。
在使用之前,迴圈裝置必須與現存檔案系統上的檔案相關聯。這種關聯將提供給使用者一個應用程式介面,介面將允許檔案視為塊特殊檔案(參見裝置檔案系統)使用。因此,如果檔案中包含一個完整的檔案系統,那麼這個檔案就能如同磁碟裝置一般被掛載。
這種裝置檔案經常被用於光碟或是磁碟映象。通過迴圈掛載來掛載包含檔案系統的檔案,便使處在這個檔案系統中的檔案得以被訪問。這些檔案將出現在掛載點目錄。如果掛載目錄中本身有檔案,這些檔案在掛載後將被禁止使用。
使用 fdisk 為磁碟分割槽(關於分割槽的一些概念不清楚的使用者請參看主引導記錄)
同樣因為環境原因中沒有物理磁碟,也無法建立虛擬磁碟的原因我們就無法實驗練習使用該命令了,下面我將以我的物理主機為例講解如何為磁碟分割槽。
# 檢視硬碟分割槽表資訊
$ sudo fdisk -l
輸出結果中開頭顯示了我主機上的磁碟的一些資訊,包括容量扇區數,扇區大小,I/O 大小等資訊。
我們重點開一下中間的分割槽資訊,/dev/sda1,/dev/sda2 為主分割槽分別安裝了 Windows 和 Linux 作業系統,/dev/sda3 為交換分割槽(可以理解為虛擬記憶體),/dev/sda4 為擴充套件分割槽其中包含 /dev/sda5,/dev/sda6,/dev/sda7,/dev/sda8 四個邏輯分割槽,因為主機上有幾個分割槽之間有空隙,沒有對齊邊界扇區,所以分割槽之間的不是完全連續的。
# 進入磁碟分割槽模式
$ sudo fdisk virtual.img
在進行操作前我們首先應先規劃好我們的分割槽方案,這裡我將在使用 128M(可用 127M 左右)的虛擬磁碟映象建立一個 30M 的主分割槽剩餘部分為擴充套件分割槽包含 2 個大約 45M 的邏輯分割槽。
操作完成後輸入p
檢視結果如下:
最後不要忘記輸入w
寫入分割槽表。
使用 losetup 命令建立映象與迴環裝置的關聯
同樣因為環境原因中沒有物理磁碟,也沒有 loop device 的原因我們就無法實驗練習使用該命令了,下面我將以我的物理主機為例講解。
$ sudo losetup /dev/loop0 virtual.img
# 如果提示裝置忙你也可以使用其它的迴環裝置,"ls /dev/loop*"參看所有迴環裝置
# 解除裝置關聯
$ sudo losetup -d /dev/loop0
然後再使用mkfs
格式化各分割槽(前面我們是格式化整個虛擬磁碟映象檔案或磁碟),不過格式化之前,我們還要為各分割槽建立虛擬裝置的對映,用到kpartx
工具,需要先安裝:
$ sudo apt-get install kpartx
$ sudo kpartx -av /dev/loop0
# 取消對映
$ sudo kpartx -dv /dev/loop0
接著再是格式化,我們將其全部格式化為 ext4:
$ sudo mkfs.ext4 -q /dev/mapper/loop0p1
$ sudo mkfs.ext4 -q /dev/mapper/loop0p5
$ sudo mkfs.ext4 -q /dev/mapper/loop0p6
格式化完成後在/media
目錄下新建四個空目錄用於掛載虛擬磁碟:
$ mkdir -p /media/virtualdisk_{1..3}
# 掛載磁碟分割槽
$ sudo mount /dev/mapper/loop0p1 /media/virtualdisk_1
$ sudo mount /dev/mapper/loop0p5 /media/virtualdisk_2
$ sudo mount /dev/mapper/loop0p6 /media/virtualdisk_3
# 解除安裝磁碟分割槽
$ sudo umount /dev/mapper/loop0p1
$ sudo umount /dev/mapper/loop0p5
$ sudo umount /dev/mapper/loop0p6
然後:
$ df -h
輕鬆一下
cowsay
命令,可以讓你在終端裡以一種動物說話的形式打印出一段話。
# 安裝
$ sudo apt-get install cowsay
# 預設是一隻牛
$ cowsay hello shiyanlou
# 加上'-l'引數列印所有支援的動物(其實不只是動物)種類
$ cowsay -l
# 使用'-f'引數選擇動物種類
$ cowsay -f elephant hello shiyanlou
# 此外它還可以結合我們之前的作業講過的 fortune 命令一起使用
$ fortune | cowsay -f daemon