分類: Linux

Linux 檔案系統掛載(mount)使用教學與範例

在 Windows 系統中如果裝了好多顆硬碟、光碟機或是隨身碟,系統就會自動幫這些設備(device)編號,例如第一顆硬碟通常就會是 C 槽,第二顆就是 D 槽,如果又有光碟機或隨身碟,就依序編下去,而在「我的電腦」中打開後,就可以存取設備(硬碟、光碟或隨身碟)中的檔案,這是大家應該都很習慣的事情。

不過在 Linux 系統中就不是這樣,所有可存取的檔案都被安置在一個很大的目錄樹(也就是根目錄「/」)底下的某ㄧ個位置,如果要存取某個設備上的檔案,就必須先把這個設備掛載(mount)上來後,才能夠讀取或寫入資料,例如在新增硬碟、存取 USB 隨身碟或是讀取 CD-ROM 時,都需要掛載的動作。

雖然現在大家常用的的 Linux distribution 大部分都有自動掛載 USB 或 CD-ROM 的功能,不過難免還是會需要用到指令的時候。這裡將介紹在 Linux 中常用的掛載方式,也就是 mountumount 兩個指令的使用方式,一般若要使用 mount 指令掛載 device,最常見的方式就是像這樣:

mount -t type device dir

其中 device 是就是要掛載的設備,而 -t type 參數是指定 device 的檔案系統格式(如 ext4vfatntfs 等),最後的 dir 則是指定掛載的路徑(也就是要把這個設備掛在目錄樹的哪裡)。

在設備存取完畢後,如果要移除設備(例如拔除 USB 隨身碟),必須要先把設備卸載,以免資料沒有同步寫入設備而造成資料損毀。要卸載設備則使用 umount 指令:

umount dir

umount 的參數只需要指定掛載的路徑即可。


以下是一些 mountumount 常見的使用範例:

掛載光碟(CD-ROM 或 DVD-ROM)

如果 Linux 有抓到光碟機,正常的情況在 /dev 中會有一個叫做 cdrom 的檔案,它是一個連結(link)檔,指到真正的設備(通常是 /dev/sr0),如果想知道,可以用 ls -l 看一下:

ls -l /dev/cdrom

輸出為:

lrwxrwxrwx 1 root root 3 2013-01-08 16:55 /dev/cdrom -> sr0

如果要讀取光碟片中的內容,先將光碟片放進光碟機後之後,執行 mount 指令:

sudo mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom

這裡將 /dev/cdrom 這個光碟機掛載到 /mnt/cdrom 這個目錄,這個目錄可以自己選擇,不過要先確認這個目錄是存在的,如果指定的目錄不存在記得要用 mkdir 先建立。

第一個參數 -t iso9660 是指定光碟的檔案格式,這個通常是不需要修改的,只要掛載光碟就是這樣使用。

另外一個參數 -o ro 參數是指定這個設備是唯讀的(read only),因為正常的光碟片只能讀取,不能寫入,所以要加上這個參數,如果想燒錄光碟片的話,就要使用其它燒錄專用的工具了。

掛載 ISO 影像檔

ISO 影像檔是常常會使用到的檔案格式(例如下載各種 Linux 的安裝光碟),通常 ISO 檔都是用來直接燒錄成光碟片,沒辦法直接讀取,如果想在 Linux 中直接讀取 ISO 檔案內容,就需要先用 mount 指令將 ISO 檔案掛載後,才能讀取其中的資料:

mount -t iso9660 -o loop /home/seal/myiso.iso /mnt/myiso

其中所使用的參數有兩個,-t iso9660 是指定 ISO 檔案格式,-o loop 則是使用 loop device 來掛載 ISO 檔,基本上這兩個參數都不需要更動,之後就是指定 ISO 檔案的位置與掛載點的位置,這樣掛載 ISO 檔案之後,/mnt/myiso 目錄中就可以看到這個 ISO 影像檔的內容了。

查看所有的掛載資訊

如果想查看系統中所有設備掛載的狀況,可以直接執行 mount 指令不加任何參數:

mount

輸出為:

/dev/sda1 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/home on /export/home type none (rw,bind)
/opt on /export/opt type none (rw,bind)
nfsd on /proc/fs/nfsd type nfsd (rw)
rpc_pipefs on /run/rpc_pipefs type rpc_pipefs (rw)
/dev/sdb1 on /media/usb type vfat (rw)
/dev/sr0 on /media/cdrom type iso9660 (ro)

上面這個輸出中的倒數第二行是一個 USB 隨身碟(/dev/sdb1),掛載路徑為 /media/usb。最後一行則是光碟,掛載路徑為 /media/cdrom

除了使用 mount 指令之外,也可以使用 df 指令:

df -h

輸出為:

檔案系統 容量 已用 可用 已用% 掛載點
/dev/sda1 116G 12G 98G 11% /
udev 16G 4.0K 16G 1% /dev
tmpfs 6.3G 344K 6.3G 1% /run
none 5.0M 0 5.0M 0% /run/lock
none 16G 0 16G 0% /run/shm
/dev/sdb1 30G 6.6G 24G 22% /media/usb
/dev/sr0 4.0G 4.0G 0 100% /media/cdrom

mount 指令所輸出的資訊較詳盡,而 df 指令則是會輸出每個儲存裝置的空間使用狀況,在一般的狀況下,若只是要看設備掛載的路徑的話,使用 df 指令就夠了。

掛載 /etc/fstab 中所有的設備(device)

Linux 系統中的 /etc/fstab 這個檔案是紀錄開機過程中會自動掛載的設備,有時候因為某些因素(例如格式化硬碟等),系統管理者會在開機過後手動 umount 某些設備,如果想要一次把 /etc/fstab 中所有的設備都掛載上去的話,可以用 mount 加上 -a 參數,以下是一個範例:

假設 /etc/fstab 的內容如下:

#
proc /proc proc nodev,noexec,nosuid 0 0
# / was on /dev/sda5 during installation
/dev/sda5 / ext4 errors=remount-ro 0 1
# /mydata was on /dev/sda6 during installation
/dev/sda6 /mydata ext2 defaults 0 2
# /backup was on /dev/sda7 during installation
/dev/sda7 /backup vfat defaults 0 3

使用 mount 指令將以上的設備全數掛載:

sudo mount -a

使用 -a 參數時,mount 指令會把 /etc/fstab 中所有的設備依照設定的路徑掛載,以這個範例而言就是將 /dev/sda6 掛載到 /mydata,而 /dev/sda7 則掛載到 /backup,而原本就已經掛載的目錄就會自動跳過,例如 /dev/sda5 這個是根目錄,一般都會是以掛載的狀態,就會自動跳過。

mount 指令查看:

mount

輸出為:

/dev/sda5 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda6 on /mydata type ext2 (rw)
/dev/sda7 on /backup type vfat (rw)
gvfs-fuse-daemon on /home/bala/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=bala)

mount-a 參數可以一次掛載所有的設備,而 umount 也有對應的 -a 參數,可以一次卸載所有的設備:

sudo umount -a

輸出為:

umount: /run/shm: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
umount: /run: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
umount: /dev: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
umount: /: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))

這時後會出現一些訊息,顯示某一些設備無法卸載,這是因為這些都是系統主要的檔案,在系統運行時無法卸載,而其餘沒有顯示的部分都會全部卸載。

掛載 /etc/fstab 中的某一項的設備

如果只是想掛載某一項設備,而這個設備剛好有寫在 /etc/fstab 中,那麼在掛載時就只需要指定掛載路徑,mount 指令會自己依照 /etc/fstab 中的設定去找到設備並掛載。

假設 /etc/fstab 中有一行設定如下:

/dev/sda6 /mydata ext2 defaults 0 2

那麼要掛載 /mydata 就只需要執行:

sudo mount /mydata

這樣 /dev/sda6 就會被掛載到 /mydata 這個位置。

除了指定掛載位置,也可以直接指定設備,也就是這樣:

sudo mount /dev/sda6

兩種寫法都可以。

查看指定檔案系統的設備

如果只想查看某一種檔案系統的掛載設備,可以使用 mount 指令配合 -l-t 兩個參數,例如查看檔案系統為 Ext2 的掛載設備:

mount -l -t ext2

輸出為:

/dev/sda6 on /mydata type ext2 (rw)

查看檔案系統為 Ext4 的掛載設備:

mount -l -t ext4

輸出為:

/dev/sda5 on / type ext4 (rw,errors=remount-ro)

使用 -l 與 -t 兩個參數時,mount 就只會列出符合指定檔案系統的設備。

掛載軟碟機

軟碟機在現在這個時代應該幾乎已經沒有人在用了,所以就簡單介紹一下指令,掛載指令為:

sudo mount /dev/fd0 /mnt/floppy

卸載指令:

sudo umount /mnt/floppy

變更設備掛載點

如果想將已經掛載的設備掛載點更換位置,一般直覺得做法是先卸載後再重新掛載,但其實有更快的方式,就是利用 --move(或 -M)參數,例如要將 /mydata 變更為 /mnt/data2,則執行:

sudo mount -M /mydata /mnt/data2

這樣原本掛載在 /mydata 的設備就會搬到 /mnt/data2 了。執行完後可以檢查一下:

mount | grep /mydata
mount | grep /mnt/data2

輸出為

/dev/sda6 on /mnt/data2 type ext2 (rw)

在不更動 /etc/mtab 的情況下掛載

在一般的狀況下 mountumount 指令會將目前的掛載狀態寫入 /etc/mtab 這個檔案中,而使用 mount 指令查看掛載狀態時就是輸出這個檔案的內容,但如果 /etc 是以唯讀(read-only)的方式掛載時,這個檔案就無法寫入,這時候可以使用 -n 參數:

sudo mount -n /dev/sda6 /mydata

這樣的掛載方式不會更新 /etc/mtab,所以在使用 mount 查看掛載狀態時,就不會出現這個設備:

mount | grep /mydata
grep /mydata /etc/mtab

這兩個都沒有任何輸出,但事實上 /dev/sda6 這個設備已經被掛載在 /mydata 上了。

cd /mydata
ls

輸出為

dir1 dir2 test

以唯讀(Read-Only)的方式掛載設備

一般正常使用 mount 指令掛載時,預設會以可讀寫(-w-o rw)的方式掛載,若要以唯讀的方式掛載設備,可以加上 --read-only-r 參數,這個參數的作用相當於 -o ro

sudo mount -r /dev/sda6 /mydata
mount | grep /mydata

輸出為

/dev/sda6 on /mydata type ext4 (ro)

雖然這裡使用唯讀的方式掛載,但若設備的檔案系統為 Ext 3 或 Ext 4,且設備之前有資料寫入不完全或錯誤的狀況(例如硬碟寫入到一半突然斷電)的話,系統還是會依照 journal 重新寫入資料到設備中,如果要避免這樣的狀況發生,就要再加入一個 noload 參數:

sudo mount /dev/sda6 /mydata -t ext4 -o ro -o noload
mount | grep /mydata

輸出為

/dev/sda6 on /mydata type ext4 (ro,noload)

將掛載點綁定(bind)至新的位置

當一個設備被掛載之後,其掛載的目錄位置稱作這個設備的掛載點,正常來說一個掛載的設備會有一個掛載點,但有些情況會需要將一個設備掛載在多的掛載點上,讓多個掛載點可以同時存取設備中的檔案,這個時候就要使用 mount 指令的 bind 的功能,加上 --bind(或是 -B)參數並指定既有的掛載點與新的掛載點:

mount --bind olddir newdir

或是用更精簡的寫法

mount -B olddir newdir

其中這樣 olddir 是原本的掛載點,而 newdir 則是新的掛載點,執行上述的指令之後,這個設備就可以同時由 olddirnewdir 這兩個地方來存取。

以下是一個實際的範例,假設某項設備已經被掛載到 /mydata 這個掛載點,我們想將這個設備重復掛載到 /mnt/data2 這個位置,則執行:

sudo mount -B /mydata /mnt/data2

接著檢查一下掛載狀態:

mount | grep /mydata

輸出為:

/dev/sda6 on /mydata type ext2 (rw)
/mydata on /mnt/data2 type none (rw,bind)

這樣就表示掛載完成了,接著測試一下,首先檢查 /mydata 中的內容:

cd /mydata
ls

輸出為:

test

接著在 /mydata 建立兩個資料夾:

mkdir dir1
mkdir dir2
ls

輸出為:

test dir1 dir2

然後再查看 /mnt/data2 中的內容:

cd /mnt/data2
ls

輸出為:

test dir1 dir2

由這個小測試就可以看得出來,/mydata/mnt/data2 這兩個資料夾其實是同一個設備,不管從哪邊存取都是一樣的,這樣大家應該就會比較瞭解 bind 的意思了。

上面的新的掛載點其掛載方式會跟原始的掛載點相同,如果想變更新掛載點的掛載選項(例如以唯讀方式掛載),則可使用 mount 指令加上 remount 參數來設定新的掛載點選項:

sudo mount --bind olddir newdir
sudo mount -o remount,ro newdir

第二行就是設定 newdir 以唯獨方式掛載。

一次卸載多個設備

若要一次卸載多個設備,可以直接使用 umount 指令加上多個挂載點參數:

sudo umount /mydata /backup

延遲(Lazy)卸載功能

有時候我們想要卸載某個設備,但這個設備還在進行一些資料的存取(例如複製檔案等),但又不想等它做完所有的事情才下 umount 指令(例如要下班了),這時候就可以使用 umount 指令的 lazy 功能,他會等到設備把所有的事情都做完之後,才進行卸載:

sudo umount -l /mydata

強制卸載設備

umount 指令有提供一個強制卸載功能,這個功能通常用於 NFS 的掛載出問題時(例如網路斷線),讓管理者可以強制把斷線的 NFS 卸載,若要強制卸載則使用 -f 參數:

sudo umount -f /mnt/data3

而有時候因為某些不明因素,卸載設備時會有問題,最常見的問題就是設備還在被某些行程(process)使用,這時候可以使用 ps 指令看看系統中有沒有什麼行程在使用要卸載的設備:

ps ajx | grep /mydata

輸出可能會像這樣:

2540 3037 3037 2468 pts/2 3037 D+ 0 0:00 cp -r /home/geekstuff/ProjectData/ /mydata

另外也可以使用 fuser 指令看看是哪一個行程在使用要卸載的設備:

fuser -cu /mydata

輸出為:

/mydata:      3087(root)

fuser 輸出會顯示行程的 ID(Process ID)與使用者名稱。透過這樣的方式,就可以很快得知到底是誰在使用這個設備了。

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Recent Posts

光陽 KYMCO GP 125 機車接電發動、更換電瓶記錄

本篇記錄我的光陽 KYMCO ...

2 年 ago

[開箱] YubiKey 5C NFC 實體金鑰

本篇是 YubiKey 5C ...

2 年 ago

[DIY] 自製竹火把

本篇記錄我拿竹子加上過期的苦茶...

3 年 ago