Contents

Linux 掛載硬碟另類方法

在 Linux 系統管理中,檔案系統的掛載是核心操作之一。自動掛載機制允許系統在開機時或在特定條件下(如插入可移動裝置)自動連接儲存裝置到指定的掛載點,無需使用者手動介入。本文整理 4 種常見又實用的作法:/etc/fstabsystemd mount/automount、udevil + devmon、以及 udev 規則,最後附上小實驗示範用 loop device 測試掛載。

閱讀重點
  • 固定本機磁碟:/etc/fstab 最直觀,但請搭配 nofailx-systemd.automount 避免開機卡住。
  • 需要依賴管理、按需掛載:systemd.mount + .automount 最穩。
  • 桌面使用者、非特權掛載 USB:udevil + devmon 很輕巧。
  • 插拔自動化、精準控制:udev 規則可客製,但建議配合 systemd 服務。

方法一:/etc/fstab(檔案系統表)

實戰

曾經寫過這篇用 fstab 做自動掛載的紀錄(延伸閱讀):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 我們需要建立一個掛載點
sudo mkdir -p /media/extHDD
# 將磁區掛載到我們剛剛建立的掛載點
sudo mount /dev/sda1 /media/extHDD
# 找出我們的磁區的 UUID
sudo blkid
# /dev/sda1: UUID="4411c5bb-2392-45d8-a7ba-7b40275a84fd" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="42f5e0d3-01"

# 在 /etc/fstab 加下面設定
UUID=4411c5bb-2392-45d8-a7ba-7b40275a84fd /media/extHDD ext4 rw,defaults,nofail 0 0

# 確認 /etc/fstab 設定無錯誤
sudo mount -a
# 可用 df -mh 確認裝置是否有掛載

說明

/etc/fstab(file system table)是 Linux 用於在開機時自動掛載檔案系統的傳統設定檔。每一行代表一個掛載配置:

<file system> <dir> <fs-type> <options> <dump> <pass>

  • <file system>:欲掛載的分割區或裝置。建議使用 UUID 或 LABEL,避免 /dev/sdX 變動。
  • <dir>:掛載點(目錄需先存在)。
  • <fs-type>:檔案系統類型,如 ext4、xfs、ntfs、vfat、cifs、nfs(或 auto)。
  • <options>:掛載選項,逗號分隔。
  • <dump>:給 dump 備份工具(通常 0)。
  • <pass>:開機 fsck 檢查順序(根 1,其他 2,不檢查 0)。

常用掛載選項

  • defaults:預設組合,相當於 rw,suid,dev,exec,auto,nouser,async
  • rw / ro:可讀寫/唯讀。
  • auto / noauto:開機或 mount -a 時是否自動掛載。
  • nofail:掛載失敗也不影響開機流程(可移動或網路磁碟必備)。
  • user/nouser/owner/group:誰可以掛載。

systemd 特定選項(寫在 fstab 也生效)

  • x-systemd.automount:建立 .automount,首次存取時才實際掛載,加速開機、避免等待。
  • _netdev:標記為網路檔案系統,等網路就緒才掛載。
  • x-systemd.device-timeout=20s:等待裝置可用的最長時間。
  • x-systemd.mount-timeout=30s:掛載超時時間。
  • x-systemd.requires=<unit>:加入 systemd 依賴關係。

設定步驟(範例)

  1. 取得裝置資訊
1
2
3
sudo lsblk -f
sudo blkid /dev/sdb1
# /dev/sdb1: UUID="12345678-abcd-1234-abcd-1234567890ab" TYPE="ext4" PARTUUID="abcdef01-1234" ...
  1. 建立掛載點
1
sudo mkdir -p /mnt/mydata
  1. 編輯 /etc/fstab
1
2
3
4
# <file system>               <dir>         <type>  <options>                <dump> <pass>
UUID=YOUR_DEVICE_UUID         /mnt/mydata   ext4    defaults,nofail           0      2
# CIFS 範例(網路磁碟):
//server/share                /mnt/myshare  cifs    credentials=/etc/samba/mycreds,uid=1000,gid=1000,_netdev,x-systemd.automount,nofail,x-systemd.device-timeout=15s 0 0
  1. 測試掛載
1
sudo mount -a
  1. 驗證
1
2
3
df -hT /mnt/mydata
# Filesystem  Type  Size  Used Avail Use% Mounted on
# /dev/sdb1   ext4   97G   60M   92G   1%  /mnt/mydata
NFS 踩雷與解法(為何會拖垮系統?)
  • NFS 是網路檔案系統,當伺服器或網路異常時,本機的 I/O 會阻塞,lscat、甚至開機流程都可能卡住(RPC timeout)。
  • 解法:使用 autofs 或在 fstab 加上 x-systemd.automount,_netdev,nofail,x-systemd.device-timeout=...,讓掛載變成「按需且可快速失敗」。
  • 小實驗:手動 mount NFS 後關閉伺服器,ls /mnt/nfs 會卡住;改用 autofs 會快速回應錯誤。

參考來源:

  • ubuntu 開機自動掛載硬碟 – Willis 的學習紀錄:https://www.weichen.idv.tw/wordpress/2023/02/20/ubuntu-%E9%96%8B%E6%A9%9F%E8%87%AA%E5%8B%95%E6%8E%9B%E8%BC%89%E7%A1%AC%E7%A2%9F/
  • Linux 檔案系統掛載(mount)使用教學與範例 – G. T. Wang:https://blog.gtwang.org/linux/linux-mount/
  • 推薦的 NFS 掛載設定(AWS EFS):https://docs.aws.amazon.com/zh_cn/efs/latest/ug/mounting-fs-nfs-mount-settings.html
  • fstab 與 _netdev 文章:https://www.cnblogs.com/chuyiwang/p/17469223.html

方法二:Systemd 掛載

實戰(掛載 /dev/sdb1/mnt/mydata

  1. 建立 .mount 單元
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# /etc/systemd/system/mnt-mydata.mount
[Unit]
Description=Mount MyData Partition
# 若為網路磁碟可加:
# After=network-online.target
# Wants=network-online.target

[Mount]
What=/dev/disk/by-uuid/YOUR_DEVICE_UUID  # 建議用 UUID
Where=/mnt/mydata
Type=ext4
Options=defaults,nofail
# DirectoryMode=0755  # 需要 systemd 自動建立掛載點時可用

[Install]
WantedBy=multi-user.target

2)(可選)建立 .automount(按需掛載)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# /etc/systemd/system/mnt-mydata.automount
[Unit]
Description=Automount MyData Partition
# ConditionPathExists=/mnt/mydata

[Automount]
Where=/mnt/mydata
# TimeoutIdleSec=300  # 空閒 5 分鐘卸載

[Install]
WantedBy=multi-user.target
  1. 套用與啟用
1
2
3
4
5
6
7
sudo systemctl daemon-reload
# 僅 .mount(開機即掛載)
sudo systemctl enable mnt-mydata.mount
sudo systemctl start mnt-mydata.mount
# 使用 .automount(按需掛載)
sudo systemctl enable mnt-mydata.automount
sudo systemctl start mnt-mydata.automount
  1. 驗證
1
2
3
4
systemctl status mnt-mydata.mount
systemctl status mnt-mydata.automount  # 若有使用
lsblk
findmnt /mnt/mydata

優缺點

  • 優點:
    • 強依賴管理(與網路、其他服務的順序整合)。
    • .automount 可按需掛載,縮短開機時間。
    • journalctl 記錄完整,便於除錯;設定錯也較不致讓系統卡住。
    • 與整體 systemd 管理模式一致,標準化。
  • 缺點:
    • 設定比 fstab 繁瑣。
    • 若用 /dev/sdX 易因裝置順序變動而失敗,應改用 /dev/disk/by-uuid 或 LABEL。
    • 對不熟悉 systemd 的使用者有學習曲線。

參考來源:

  • 用 systemd 實現自動掛載:https://ruohai.wang/202401/systemd-auto-mount-sdcard/
  • 使用 systemd 開機掛載硬碟:https://www.expoli.tech/articles/2022/12/23/use-systemd-mount-any-device
  • fstab 與 systemd.mount 的研究:https://zhangguanzhang.github.io/2019/01/30/fstab/

方法三:udevil(搭配 devmon)

適合在非特權使用者環境下,自動掛載可移動媒體(USB、光碟)。

A. 概念

  • udevil:命令列工具,讓一般使用者依 /etc/udevil/udevil.conf 規則掛/卸載,無須 sudo
  • devmon:常駐程式,監控裝置插拔並呼叫 udevil 自動掛/卸載,可設定掛載後開啟檔案管理器等動作。

B. 安裝與(必要時)SUID 設定

1
2
sudo apt-get update
sudo apt-get install udevil
SUID 提醒

一般以套件安裝不需要手動調整。若自行編譯安裝才可能需要設定 SUID root:

1
2
sudo chown root:root /usr/bin/udevil
sudo chmod u+s,go-s,ugo+x /usr/bin/udevil

請審慎評估安全性;或限制執行於特定群組(如 plugdev)。

C. 基本用法

1
2
3
4
5
6
7
8
# 以預設路徑掛載(通常掛在 /media 下)
udevil mount /dev/sdb1
# 指定掛載點(需 conf 允許)
udevil mount /dev/sdb1 /media/myusb
# 卸載
udevil umount /dev/sdb1
# 或
udevil umount /media/myusb

D. devmon 自動掛載與常用選項

1
2
3
4
5
6
# 於使用者登入環境啟動(例如 ~/.xsessionrc)
devmon &
# 掛載後打開檔案管理器
devmon --exec-on-mount "thunar %d" &
# 指定掛載選項
devmon --mount-options "noatime,nodiratime" &

以 systemd 啟用使用者服務方式自動啟動:

1
2
# 系統層:devmon@<username>.service 已存在時可這樣啟用
sudo systemctl enable devmon@"$(whoami)"

E. udevil.conf 常見選項

  • allowed_devices:允許掛載的裝置(可用萬用字元 /dev/sd*/dev/sr*)。
  • allowed_internal_devices:允許的內部裝置(謹慎)。
  • allowed_types:允許的檔案系統(如 vfat, exfat, ntfs, ext4, iso9660, cifs, nfs)。
  • allowed_media_dirs:可建立掛載點的目錄(如 /media, /run/media/$USER)。
  • default_options_<fstype>:各檔案系統的預設掛載選項(例:default_options_vfat = noatime,flush)。
  • forbidden_options:禁止的掛載選項。

優缺點

  • 優點:一般使用者也能掛載、輕量、設定直覺;桌面環境很好用。
  • 缺點:多半依賴使用者登入會話;可能與桌面環境自帶(udisks2/GVfs)機制重疊;SUID 帶來安全風險。

參考來源:

  • udevil 自動掛載 USB(範例):https://mgh.cool:9090/post/ubuntu%e4%bd%bf%e7%94%a8udevil%e8%87%aa%e5%8a%a8%e6%8c%82%e8%bd%bdu%e7%9b%98
  • Archlinux 的 U 盤自動裝載(udevil):https://www.cnblogs.com/ccpaging/p/4760051.html

方法四:udev 規則

實戰(範例規則:USB/SD 插入自動掛載、移除自動卸載)

1
sudo nano /etc/udev/rules.d/99-usb-automount.rules
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# add USB
ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", SUBSYSTEMS=="usb", \
  ENV{MOUNT_PATH}="/media/$env{ID_FS_LABEL_ENC}-$env{ID_PART_TABLE_UUID}", \
  RUN+="/bin/mkdir -p '$env{MOUNT_PATH}'", \
  RUN+="/bin/systemd-mount -o relatime,sync,umask=022 --no-block --collect $env{DEVNAME} '$env{MOUNT_PATH}'"
# add SD
ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", ATTRS{type}=="SD", \
  ENV{MOUNT_PATH}="/media/$env{ID_FS_LABEL_ENC}-$env{ID_PART_TABLE_UUID}", \
  RUN+="/bin/mkdir -p '$env{MOUNT_PATH}'", \
  RUN+="/bin/systemd-mount -o relatime,sync,umask=022 --no-block --collect $env{DEVNAME} '$env{MOUNT_PATH}'"
# remove
ACTION=="remove", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", \
  ENV{MOUNT_PATH}="/media/$env{ID_FS_LABEL_ENC}-$env{ID_PART_TABLE_UUID}", \
  RUN+="/bin/systemd-mount --umount '$env{MOUNT_PATH}'", \
  RUN+="/bin/rmdir $env{MOUNT_PATH}"

參考來源:https://mgh.cool:9090/post/linux%e4%bd%bf%e7%94%a8udev%e5%ae%9e%e7%8e%b0%e8%87%aa%e5%8a%a8%e6%8c%82%e8%bd%bdu%e7%9b%98

深入探討與建議流程

  • udev 是核心的裝置管理器,透過規則匹配裝置屬性(如 SUBSYSTEMKERNELidVendor/idProductID_FS_UUID 等)來決定要執行的動作。
  • 現代系統建議讓 udev 觸發 systemd 服務處理較複雜的動作,避免在 udev 的狹小執行環境直接 mount

撰寫規則前先盤點裝置屬性

1
2
# 以 /dev/sdb1 為例:
sudo udevadm info -a -p $(udevadm info -q path -n /dev/sdb1)

範例:以 UUID 指定裝置並呼叫腳本(簡化版)

1
2
3
# /etc/udev/rules.d/80-usb-automount.rules
ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", ENV{ID_FS_UUID}=="1234-ABCD", RUN+="/usr/local/bin/mount_usb.sh %k"
ACTION=="remove", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", ENV{ID_FS_UUID}=="1234-ABCD", RUN+="/usr/local/bin/umount_usb.sh %k"

更穩健的作法是交給 systemd(模板服務):

1
2
# 由 udev 提示 systemd 啟動服務
ACTION=="add", KERNEL=="sd[a-z][0-9]*", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="YOUR-UUID", TAG+="systemd", ENV{SYSTEMD_WANTS}="usb-mount@%k.service"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# /etc/systemd/system/usb-mount@.service
[Unit]
Description=USB Mount for %I
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/mount_usb.sh %I
ExecStop=/usr/local/bin/umount_usb.sh %I

[Install]
WantedBy=multi-user.target

掛載/卸載腳本(可運行範例)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
# /usr/local/bin/mount_usb.sh
# 用法:mount_usb.sh sdb1
set -euo pipefail
DEVICE_KERNEL_NAME="${1:?kernel name required}"   # 例如 sdb1
DEV="/dev/${DEVICE_KERNEL_NAME}"
MOUNT_POINT_BASE="/media/usb"

# 取 UUID 與檔案系統
DEVICE_UUID=$(blkid -s UUID -o value "$DEV" || true)
FSTYPE=$(blkid -s TYPE -o value "$DEV" || echo ext4)
if [ -z "${DEVICE_UUID}" ]; then
  logger "mount_usb.sh: Could not get UUID for $DEV"
  exit 1
fi

MOUNT_POINT="${MOUNT_POINT_BASE}-${DEVICE_UUID}"
mkdir -p "$MOUNT_POINT"

# 請視環境調整 uid/gid(此處以 1000:1000 範例)
if mount -t "$FSTYPE" -o defaults,rw,uid=1000,gid=1000 "$DEV" "$MOUNT_POINT"; then
  logger "mount_usb.sh: Mounted $DEV at $MOUNT_POINT"
else
  logger "mount_usb.sh: Failed to mount $DEV"
  rmdir "$MOUNT_POINT" || true
  exit 1
fi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# /usr/local/bin/umount_usb.sh
# 用法:umount_usb.sh sdb1
set -euo pipefail
DEVICE_KERNEL_NAME="${1:?kernel name required}"   # 例如 sdb1
MOUNT_POINT_BASE="/media/usb"

# 優先用 UUID 還原掛載點
DEVICE_UUID=$(blkid -s UUID -o value "/dev/${DEVICE_KERNEL_NAME}" 2>/dev/null || true)
if [ -n "$DEVICE_UUID" ]; then
  MOUNT_POINT="${MOUNT_POINT_BASE}-${DEVICE_UUID}"
else
  # 後備:依裝置尋找掛載點
  MOUNT_POINT=$(findmnt -n -o TARGET "/dev/${DEVICE_KERNEL_NAME}" || true)
fi

if [ -n "${MOUNT_POINT:-}" ] && [ -d "$MOUNT_POINT" ]; then
  if umount "$MOUNT_POINT"; then
    logger "umount_usb.sh: Unmounted $MOUNT_POINT"
    rmdir "$MOUNT_POINT" 2>/dev/null || true
  else
    logger "umount_usb.sh: Failed to unmount $MOUNT_POINT (already unmounted or busy)"
  fi
else
  logger "umount_usb.sh: Mount point for /dev/${DEVICE_KERNEL_NAME} not found"
fi

記得為腳本賦予執行權限:

1
sudo chmod +x /usr/local/bin/mount_usb.sh /usr/local/bin/umount_usb.sh

參考來源:

  • Linux 使用 udev 實作自動掛載 U 盤:https://mgh.cool:9090/post/linux%e4%bd%bf%e7%94%a8udev%e5%ae%9e%e7%8e%b0%e8%87%aa%e5%8a%a8%e6%8c%82%e8%bd%bdu%e7%9b%98
  • u 盤自動掛載/拷貝資料(示例):https://www.cnblogs.com/duoruaimi4/p/16336631.html
  • Autofs 自動掛載(筆記):https://hackmd.io/@yzai/HJTg6IWG5
  • iThome 相關討論:https://ithelp.ithome.com.tw/m/articles/10306536

測試掛載方法(loop device 小實驗)

想快速在不影響真實磁碟的情況下測試掛載行為,建議在 VM(例如 Multipass)裡用檔案映像搭配 loop 掛載:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 進入 VM(以 my-vm 為例)
multipass shell my-vm

# 建立 100MB 映像檔並格式化
dd if=/dev/zero of=testdisk.img bs=1M count=100
mkfs.ext4 testdisk.img

# 掛載到 /mnt/testdisk
mkdir -p /mnt/testdisk
sudo mount -o loop testdisk.img /mnt/testdisk

# 驗證
df -h /mnt/testdisk

# 卸載與清理
sudo umount /mnt/testdisk
rm testdisk.img

延伸測試:

  • mkfs.xfs testdisk.img 測 XFS;
  • mount -o loop,noatime testdisk.img /mnt/testdisk 測掛載選項;
  • losetup 觀察多個 loop device 行為。

心智圖(摘要)

mindmap root((Linux 掛載硬碟另類方法)) fstab UUID / LABEL x-systemd.automount _netdev, nofail 優點:簡單、標準 風險:設定錯會卡機 systemd .mount + .automount 依賴管理 / 日誌 建議用 /dev/disk/by-uuid udevil + devmon 非特權使用者 桌面自動掛載 SUID 風險評估 udev 規則 動態裝置事件 建議觸發 systemd 服務 腳本 mount/umount 測試 loop device Multipass VM

總結

  • 固定本機磁碟、服務啟動就要用到:/etc/fstabsystemd .mount,並搭配 x-systemd.automountnofail 等選項提升穩定度。
  • 動態插拔或桌面體驗:udevil + devmon 上手快、權限友善。
  • 高度客製的即時反應:udev 規則最靈活,但建議交由 systemd 服務實做具狀態與日誌的操作。