新建一個 udev 的規則文件即可。
udev 會監聽移動設備的 插拔 等動作並執行規則中的任務。
即可實現移動設備熱插拔時自動掛載和卸載。
代碼如下:
KERNEL!="sd[b-z]?", GOTO="automount_exit"
ACTION=="add", SUBsystem=="block", RUN+="/bin/mkdir /media/%E{ID_FS_LABEL}-%E{ID_FS_UUID}", RUN+="/bin/mount -o uid=1000,user,codepage=936,utf8 $root/%k /media/%E{ID_FS_LABEL}-%E{ID_FS_UUID}"
ACTION=="remove", SUBSYSTEM=="block", RUN+="/bin/umount /media/%E{ID_FS_LABEL}-%E{ID_FS_UUID}", RUN+="/bin/rmdir /media/%E{ID_FS_LABEL}-%E{ID_FS_UUID}"
LABEL="automount_exit"
保存在 /etc/udev/rules.d/my_auto_mount.rules
第一行用 glob
跳過名稱非 sd[b-z]?
字樣的。
%E{ID_FS_LABEL}
是卷標,%E{ID_FS_UUID}
是 UUID
,第二行就是檢測 add
事件,先根據卷標和 UUID
在/media/
下創建一個目錄然後掛載。
第三行是相應的卸載命令。
## 中文問題
如果u盤的名稱是在Windows上命名成中文然後插到linux上,就識別不了正確的中文名稱。
這時候可以修改變量 ID_FS_LABEL 為 ID_FS_LABEL_ENC
重新插入u盤後,在 /media/ 下顯示的名稱就是 gbk 編碼的名稱,類似:
/media/\xc7?\xae\xb5\xc4-B4FE-5315
實際上正常的名稱是:
/media/親愛的-B4FE-5315
所以,如果應用中要顯示正常的中文的話,只需要編碼轉換一下即可,如,python可以這樣:
disk_name = mountpoint.split('/')[-1] # 獲取掛在的目錄後截取不正常的一段
# disk_name == '\xc7?\xae\xb5\xc4-B4FE-5315'
print 'disk_name_in_chinese: ', (eval("'"+disk_name+"'")).decode('gbk').encode('utf-8')
>>> 親愛的-B4FE-5315
另:
1) 不知道還有沒有其他解決中文問題的方案,像:
1, 修改系統設置
2, udev 相關配置,或通過導入外部程序解決
2) 還有一種實現方式是修改 fstab 文件
但是有幾個弊端:
1. 需要知道 設備的信息,且要頻繁修改 fstab 文件
2. 這是在已知設備信息的情況下的處理方式,如果不能知道呢,比如機器賣出去給客戶使用了。
3. 並且只在系統啟動時才掛載 fstab 中配置的設備,
當然也可以使用 mount -a (模擬開機自動掛載操作)
3) 另一種實現開機自動掛載的方法:
修改 /etc/rc.local 文件, 加入:
for dev in $(ls -1 /dev/disk/by-label/* | grep -v EFI) ; do
label=$(basename $dev)
mkdir -p /media/$label
$(mount | grep -q /media/$label) || mount $dev /media/$label
done
4) 設備在目錄 /dev/disk/ 下按照不同的屬性羅列,可以到這裏查看相關信息
bwhite@os:/dev$ ll disk/
total 0
drwxr-xr-x 6 root root 120 12月 24 14:22 ./
drwxr-xr-x 20 root root 4380 12月 24 14:22 ../
drwxr-xr-x 2 root root 240 12月 24 14:22 by-id/
drwxr-xr-x 2 root root 60 12月 24 14:22 by-label/
drwxr-xr-x 2 root root 160 12月 24 14:22 by-path/
drwxr-xr-x 2 root root 100 12月 24 14:22 by-uuid/
bwhite@os:/dev$
udevadm的使用
udevadm是一個udev的管理工具,可以用來監視和控制udev運行時的行為,請求內核事件,管理事件隊列,以及提供簡單的調試機制。
udevadm info
這個命令實際上和數據庫的sql語句差不多,--query=查詢的內容,其他的參數都是查詢條件
例1:
udevadm info --query=all --name=sda 查詢sda的所有信息
等價於select * from devicedb where name=sda
例2:
udevadm info --query=path --name=sda
out>>/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda
等價於select path from devicedb where name=sda
udev 下載地址: https://www.kernel.org/pub/linux/utils/kernel/hotplug/
udevinfo
敲入udevinfo大概就是你用來創建規則的最直接的工具了。你需要知道的全部就是設備的sysfs設備路徑. 下面是一個精簡的例子:
# udevinfo -a -p /sys/block/sda
looking at device '/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
ATTR{stat}==" 128535 2246 2788977 766188 73998 317300 3132216 5735004 0 516516 6503316"
ATTR{size}=="234441648"
ATTR{removable}=="0"
ATTR{range}=="16"
ATTR{dev}=="8:0"
looking at parent device '/devices/pci0000:00/0000:00:07.0/host0/target0:0:0/0:0:0:0':
KERNELS=="0:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{ioerr_cnt}=="0×0"
ATTRS{iodone_cnt}=="0×31737"
ATTRS{iorequest_cnt}=="0×31737"
ATTRS{iocounterbits}=="32"
ATTRS{timeout}=="30"
ATTRS{state}=="running"
ATTRS{rev}=="3.42"
ATTRS{model}=="ST3120827AS "
ATTRS{vendor}=="ATA "
ATTRS{scsi_level}=="6"
ATTRS{type}=="0"
ATTRS{queue_type}=="none"
ATTRS{queue_depth}=="1"
ATTRS{device_blocked}=="0"
looking at parent device '/devices/pci0000:00/0000:00:07.0':
KERNELS=="0000:00:07.0"
SUBSYSTEMS=="pci"
DRIVERS=="sata_nv"
ATTRS{vendor}=="0×10de"
ATTRS{device}=="0×037f"
參考rules文件
KERNEL!="sd[a-z][0-9]", GOTO="media_by_label_auto_mount_end"
# Import FS infos
IMPORT{program}="/sbin/blkid -o udev -p %N"
# Get a label if present, otherwise specify one
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="usbhd-%k"
# Global mount options
ACTION=="add", ENV{mount_options}="relatime,sync"
# Filesystem-specific mount options
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,uid=1000,gid=1000,umask=002"
# Mount the device
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"
# Clean up after removal
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
# Exit
LABEL="media_by_label_auto_mount_end"
mount基本語法
mount [參數] /dev/sdb1(需要掛載的分區) /sdb1(掛載目錄)
參數是可選的,也可以不帶參數,參數的使用方法(-o ro,sync,atime)。
參數:
-t:指定文件系統類型
mount -t ext4 /dev/sdb1 /sdb1
-o:指定掛載選項
ro,rw:只讀或者讀寫的方式掛載,默認是rw.
sync:不適用緩存,所有操作直接讀寫磁盤。
async:適用緩存,默認方式。
noatime:每次訪問文件時不更新文件的訪問時間。
atime:每次訪問文件時更新文件的訪問時間,默認方式。
user:任何用戶都可以掛載
nouser:只有超級用戶才可以掛載
auto:系統開機自動掛載
noauto:系統開機不自動掛載
remount:重新掛載文件系統。
參考鏈接:
Linux 掛載管理(mount)
udev使用筆記
http://www.jianshu.com/p/dd6cecd7755a
Linux裏udev的工作原理
使用 udev 高效、動態地管理 Linux 設備文件
https://www.ibm.com/developerworks/cn/linux/l-cn-udev/
udev 自動掛載u盤(轉載加修改),經過測試
https://my.oschina.net/dengyz/blog/477703
How to configure to record data to pendrive instantly?
https://maskray.me/blog/2011-08-12-udev-automount-usb
https://bugs.launchpad.net/ubuntu/+source/hal/+bug/347370
https://cgit.freedesktop.org/hal/commit/?id=97b023f94f1d79a19bc0489c0d167bdaebb765fd
Automatically mount external drives to /media/LABEL on boot without a user logged in?
linux mount / umount 命令的基本用法 及 開機自動掛載
udev 中文手冊 譯者:金步國
Tags: windows python linux 熱插拔 Linux
文章來源: