我們在 Windows WSL串接 USB-RS422 與 PPP裡面介紹了如何掛載 USB 實體裝置到 WSL,本篇我們要介紹如何自動掛載 USB 隨身碟。由於 WSL Kernel 要重新編譯,如果你的 kernel 沒有重編過,請先參考前文。沒有重編過的 kernel, 會因缺乏 driver,在 WSL 可以看到裝置插入訊息,但不能驅動,不會產生 /dev/sdX。
前言
本文示範如何在 Ubuntu 18.04(或其他以 systemd 為 init 的 Linux 發行版)上,實作一套「插入 USB 隨身碟後自動掛載、廣播提示一般使用者可以使用、並提供一般使用者以 sudo 免密碼安全卸載」的完整流程。
規劃
整體設計重點如下:
- 使用 udev 偵測 USB mass storage 分割區(例如 /dev/sdd1)。
- udev 不直接執行 mount,而是透過觸發一個 systemd 範本服務 usb-mount@.service。以免因namespace不同,而讓一般用戶看不到mount
- systemd 服務執行 usb-auto-mount.sh,在「正常的 mount namespace」中掛載隨身碟,並廣播提示所有終端機。
- 提供 usb-safe-remove.sh,負責 umount(與選擇性 power-off),再廣播「可以安全拔除」。
- 透過 sudoers 設定,讓屬於 usbmount 群組的一般使用者可免密碼執行 usb-safe-remove.sh。
相較於直接在 udev 的 RUN+= 中呼叫 mount,這種「udev + systemd」的設計可以避免 systemd-udevd 預設的 PrivateMounts=yes 所帶來的 mount namespace 問題,確保掛載在整個系統中可見。
udev + systemd 自動掛載 USB 隨身碟,並以 sudo 免密碼卸載
環境假設與目標
- 作業系統:Ubuntu 18.04(採用 systemd)
- USB 裝置:一般 USB 隨身碟 / USB 行動硬碟,經由 usb-storage driver 管理
- 目標:
- 插入 USB 隨身碟後,自動掛載到 /usb(或你指定的掛載點)
- 掛載成功後,對所有登入終端機(tty / pts)顯示提示訊息
一般使用者可用 sudo usb-safe-remove.sh 免密碼安全卸載
自動掛載腳本 usb-auto-mount.sh
首先建立主腳本,負責:
- 接收裝置節點(例如 /dev/sdd1)
- 使用 mount -o sync 掛載裝置
- 對所有 tty / pts 廣播掛載成功或失敗訊息
建立檔案 /usr/local/sbin/usb-auto-mount.sh:
內容如下:
|
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 mywall() { MSG="$1" for tty in /dev/ty[0-9]* /dev/pts/*; do if [ -w "$tty" ];then echo "$MSG" > "$tty" fi done } DEV="$1" [ -z "$DEV" ] && exit 1 BLK=`echo $DEV | cut -b 1-8` mkdir -p /usb /bin/mount -o sync,uid=0,gid=0,umask=000 "${BLK}1" /usb if [ $? -eq 0 ];then mywall "${BLK}1 掛載成功" else mywall "${BLK}1 掛載失敗!!!!!!!!!!!!" fi exit 0 |
儲存後,賦予執行權限:
|
1 |
sudo chmod +x /usr/local/sbin/usb-auto-mount.sh |
建立 systemd 範本服務 usb-mount@.service
為避免 systemd-udevd 的 PrivateMounts 問題,我們不直接在 udev 內執行 mount,而是透過 systemd 啟動一個 oneshot 服務來呼叫 usb-auto-mount.sh。
檔案 /etc/systemd/system/usb-mount@.service,內容如下:
|
1 2 3 4 5 6 7 8 9 10 |
[Unit] Description=USB auto mount for %I After=local-fs.target [Service] Type=oneshot ExecStart=/usr/local/sbin/usb-auto-mount.sh /dev/%I [Install] WantedBy=multi-user.target |
建立完成後,重新載入 systemd 設定:
|
1 |
sudo systemctl daemon-reload |
建立 udev 規則偵測 USB 隨身碟
我們希望只對真正的 USB mass storage 分割區自動掛載,因此 rule 需要過濾:
- SUBSYSTEM==”block”:只處理 block 裝置
- KERNEL==”sd[b-z][0-9]”:略過 sda(系統碟),只看 sdb1、sdc1… 等外接磁碟分割區
- SUBSYSTEMS==”usb”、ENV{ID_BUS}==”usb”、ENV{ID_USB_DRIVER}==”usb-storage”:確定是 USB mass storage
- ENV{ID_FS_USAGE}==”filesystem”:只處理有檔案系統的分割區
- 透過 ENV{SYSTEMD_WANTS} 觸發 usb-mount@%k.service
建立 /etc/udev/rules.d/99-usb-auto-mount.rules,內容如下:
|
1 2 3 4 |
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[b-z][0-9]", \ SUBSYSTEMS=="usb", ENV{ID_BUS}=="usb", ENV{ID_USB_DRIVER}=="usb-storage", \ ENV{ID_FS_USAGE}=="filesystem", \ ENV{SYSTEMD_WANTS}="usb-mount@%k.service" |
儲存後,重新載入 udev 設定:
|
1 |
sudo udevadm control --reload |
建立安全卸載腳本 usb-safe-remove.sh
掛載完成後,要安全移除隨身碟,必須在實體拔除前執行 umount。以下腳本提供一個簡單的「一鍵安全移除」機制:
建立 /usr/local/sbin/usb-safe-remove.sh,內容如下:
|
1 2 3 4 |
#!/bin/bash sync sync sudo umount /usb |
儲存後給予執行權限:
|
1 |
sudo chmod +x /usr/local/sbin/usb-safe-remove.sh |
一般使用流程為:
- 插入隨身碟 → udev + systemd 自動掛載到 /usb,並廣播「已就緒」。
- 使用中可在 /usb 讀寫檔案。
- 要拔除時,一般使用者執行 sudo usb-safe-remove.sh。
設定 sudo 免密碼執行安全卸載
為了兼顧便利性與安全性,我們只讓特定群組 usbmount 的成員可以「免密碼 sudo 執行 usb-safe-remove.sh」,而不是把所有 sudo 都設成免密碼。
- 建立群組 usbmount(若已存在會顯示錯誤,可忽略):
sudo groupadd usbmount - 將需要操作隨身碟的使用者加入 usbmount 群組(以 user 為例):
sudo usermod -aG usbmount user
- 建立 sudoers 設定檔, sudo visudo -f /etc/sudoers.d/usbmount 並輸入:
%usbmount ALL=(root) NOPASSWD: /usr/local/sbin/usb-safe-remove.sh
- 完成後,加入 usbmount 群組的使用者就可以 sudo usb-safe-remove.sh 在不輸入密碼的情況下安全卸載 /usb。使用者需重新登入一次,群組才會生效。
說明:
– %usbmount:代表 usbmount 群組。
– ALL=(root):允許在任意主機上以 root 身份執行。
– NOPASSWD:執行指定指令時不需要輸入密碼。
– 僅限 /usr/local/sbin/usb-safe-remove.sh 這一支腳本免密碼,其他 sudo 指令仍需密碼。
usbipd 自動掛載
由於在 WSL 中,插拔 USB 裝置/或重開系統後,還需重新 attach,可利用下列 batch file 來進行自動 attach 的動作。
|
1 2 3 4 5 6 |
:again usbipd attach -a --wsl -b 1-4 timeout/t 2 goto again exit: |
Mount 網路磁碟機
若網路磁碟機未出現在 df 內,可自行在 /mnt 內建立掛載點,在以下列指令執行掛載
|
1 2 3 4 5 |
#!/bin/bash mount -t drvfs W: /mnt/w mount -t drvfs V: /mnt/v mount -t drvfs X: /mnt/x mount -t drvfs Z: /mnt/z |
結語
透過 udev + systemd + 自訂腳本,我們可以在 Ubuntu 18.04 上建立一套既實用又相對安全的 USB 隨身碟自動掛載與卸載機制:
– udev 負責偵測 USB mass storage 裝置並觸發 systemd 服務。
– systemd 服務在正確的 mount namespace 中執行掛載腳本。
– 掛載與卸載腳本負責實際 mount/umount,以及對所有終端機廣播狀態。
– sudoers 適度放行,使一般使用者能以 sudo 免密碼安全移除裝置,而不暴露整體系統。
依照本文步驟完成設定後,你應該就能達成:
「插上 USB → 自動掛載並在所有終端機顯示『可以用了』;
執行 sudo usb-safe-remove.sh → 安全卸載並顯示『可以拔了』」
的完整工作流程。



