在 Windows 系統中如果裝了好多顆硬碟、光碟機或是隨身碟,系統就會自動幫這些設備(device)編號,例如第一顆硬碟通常就會是 C 槽,第二顆就是 D 槽,如果又有光碟機或隨身碟,就依序編下去,而在「我的電腦」中打開後,就可以存取設備(硬碟、光碟或隨身碟)中的檔案,這是大家應該都很習慣的事情。
不過在 Linux 系統中就不是這樣,所有可存取的檔案都被安置在一個很大的目錄樹(也就是根目錄「/
」)底下的某ㄧ個位置,如果要存取某個設備上的檔案,就必須先把這個設備掛載(mount)上來後,才能夠讀取或寫入資料,例如在新增硬碟、存取 USB 隨身碟或是讀取 CD-ROM 時,都需要掛載的動作。
雖然現在大家常用的的 Linux distribution 大部分都有自動掛載 USB 或 CD-ROM 的功能,不過難免還是會需要用到指令的時候。這裡將介紹在 Linux 中常用的掛載方式,也就是 mount
與 umount
兩個指令的使用方式,一般若要使用 mount
指令掛載 device,最常見的方式就是像這樣:
mount -t type device dir
其中 device
是就是要掛載的設備,而 -t type
參數是指定 device
的檔案系統格式(如 ext4
、vfat
或 ntfs
等),最後的 dir
則是指定掛載的路徑(也就是要把這個設備掛在目錄樹的哪裡)。
在設備存取完畢後,如果要移除設備(例如拔除 USB 隨身碟),必須要先把設備卸載,以免資料沒有同步寫入設備而造成資料損毀。要卸載設備則使用 umount
指令:
umount dir
umount
的參數只需要指定掛載的路徑即可。
以下是一些
mount
與 umount
常見的使用範例:
掛載光碟(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
的情況下掛載
在一般的狀況下 mount
與 umount
指令會將目前的掛載狀態寫入 /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
則是新的掛載點,執行上述的指令之後,這個設備就可以同時由 olddir
與 newdir
這兩個地方來存取。
以下是一個實際的範例,假設某項設備已經被掛載到 /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)與使用者名稱。透過這樣的方式,就可以很快得知到底是誰在使用這個設備了。
3 則自動引用通知