Linux无桌面环境下,实现USB的自动挂载/卸载


linux无桌面环境是无法自动挂载和卸载USB设备的,需要通过mount和umount命令实现手动挂载卸载,今天就讲一下无桌面环境下Linux如何实现USB设备的自动挂载和卸载。

1.gnome桌面环境如何实现USB的自动挂载

  • 首先我们要了解gnome桌面环境如何实现USB的自动挂载的。U盘的热拔插/自动挂载跟linux2.6 kernel、 udev、 hal、 dbus 、gnome-mount 、thunar的关系。gnome 下的自动挂载主要是利用hal(HAL, Hardware abstraction layer)实现的。硬件抽象层(hal)是一个守护进程,它允许桌面应用程序即时读取硬件信息,这样,无论接口或设备类型如何,应用程序都能找到并使用它们。用这种方法,图形界面以一种无缝、一致的模式为用户提供所有的资源。
  • 具体步骤如下
插入新设备后, 
	kernel 发现设备变化反应到 sysfs 上并通知 udev, 
	udev 把硬件相关内容送给 hal, 
	hal 过滤、处理之后发送信息到 dbus 总线, 
	thunar  dbus 收到信息后在 xfdesktop 桌面显示新图标, 
	用户点击桌面图标后用 pmount 把设备挂上,打开挂载目录。(gnome缺省使用 gnome-mount )

具体信息参考:https://blog.csdn.net/du_qi/article/details/72803030

2.udev

  • udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目录底下的设备节点。它同时也用来接替devfs及热插拔的功能,这意味着它要在添加/删除硬件时处理/dev目录以及所有用户空间的行为,包括加载固件及Linux 2.6.13内核。
  • /etc/udev/rules.d下面可能有好几个udev规则文件,这些文件一部分是udev包安装的,另外一部分则是可能是别的硬件或者软件包生成的。规则文件里的规则有一系列的键/值对组成,键/值对之间用逗号(,)分割。每一个键或者是用户匹配键,或者是一个赋值键。这些值将影响udev创建的设备文件。赋值键可以处理一个多值列表。
  • udev 规则的匹配键
    ACTION:          事件 (uevent) 的行为,例如:add( 添加设备 )、remove( 删除设备 )
	KERNEL:          内核设备名称,例如:sda, cdrom。
	DEVPATH:          设备的 devpath 路径。
	SUBSYSTEM:        设备的子系统名称,例如:sda 的子系统为 block。
	BUS:            设备在 devpath 里的总线名称,例如:usb。
	DRIVER:           设备在 devpath 里的设备驱动名称,例如:ide-cdrom。
	ID:             设备在 devpath 里的识别号。
	SYSFS{filename}     设备的 devpath 路径下,设备的属性文件“filename”里的内容。
               在一条规则中,可以设定最多五条 SYSFS  匹配键。
	ENV{key}          环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键。
	PROGRAM:        调用外部命令。
	RESULT:           外部命令 PROGRAM 的返回结果。

3.单个设备自动挂载/卸载

  • 一般固定的usb设备是/dev/sdxx 的形式,先在/media下建一个usb目录用于挂载。在/etc/udev/rules.d下面创建udev规则文件,以.rules结尾,内容如下:
SUBSYSTEM=="block", KERNEL=="sdb1", ACTION=="add", NAME="Myusb", SYMLINK+="Myusb_link", RUN+="/bin/bash /home/usbadd.sh"
SUBSYSTEM=="block", KERNEL=="sdb1", ACTION=="remove", RUN+="/bin/bash /home/usbremove.sh"

注意:KERNEL==XXXX要根据/dev/sdxx做相应的修改。

  • /home下建立两个文件:

/home/usbadd.sh
内容:

mount /dev/Myusb_link /media/usb

/home/usbremove.sh
内容:

umount /dev/sdb1

注意:新版本的udev可能会遇到mount失效的问题,通过查询资料可知,udev的rules运行于独立的文件空间上,与用户的文件空间不同,因此及时挂载上了,用户也无法访问。因此需要将udev的运行方式改为共享。
修改方式如下:

	vim /lib/systemd/system/systemd-udevd.service
	// 修改
	MountFlags=shared 

此方法只能挂载单个usb设备,脚本比较简单,而且不能实现ntfs格式的usb挂载,下面介绍的usbmount工具功能比较完善。

4.usbmount工具实现自动挂载卸载

usbmount是一个完善的USB自动挂载卸载工具,只需要修改一些配置文件即可使用。但是NTFS格式的U盘需要做一些改动,将ntfs添加到usbmount。

  1. 安装

安装usbmount

sudo apt-get install usbmount

安装NTFS驱动程序包ntfs-3g

sudo apt-get install ntfs-3g
  1. 配置usbmount
sudo vim /etc/usbmount/usbmount.conf

有一行叫FILESYSTEMS=""。仅通过usbmount挂载此行中指定的文件系统,因此我们将其更改为:

FILESYSTEMS="vfat ntfs fuseblk ext2 ext3 ext4 hfsplus"

如果要使用usbmount挂载NTFS文件系统,请确保将ntfs和fuseblk添加到该行。如果您未在配置中添加fuseblk,则拔出的NTFS设备将不会自动卸载。它们将保持挂载状态并保留其挂载文件夹,直到手动卸载。

下一条是FS_MOUNTOPTIONS=""。在这里,指定应挂载哪些文件系统以及如何挂载它们。我们将其更改为:

FS_MOUNTOPTIONS="-fstype=ntfs-3g,nls=utf8,umask=007,gid=46 -fstype=fuseblk,nls=utf8,umask=007,gid=46 -fstype=vfat,gid=1000,uid=1000,umask=007"
  1. 保持NTFS挂载,直到拔出设备

已安装的NTFS驱动器只能访问几秒钟时,下面是该问题的解决方案
创建文件usbmount.rules在/etc/udev/rules.d/下

sudo vim /etc/udev/rules.d/usbmount.rules

内容如下:

KERNEL=="sd*", DRIVERS=="sbp2",         ACTION=="add",  PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c"
KERNEL=="sd*", SUBSYSTEMS=="usb",       ACTION=="add",  PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c"
KERNEL=="ub*", SUBSYSTEMS=="usb",       ACTION=="add",  PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c"
KERNEL=="sd*",                          ACTION=="remove",       RUN+="/usr/share/usbmount/usbmount remove"
KERNEL=="ub*",                          ACTION=="remove",       RUN+="/usr/share/usbmount/usbmount remove"

创建usbmount@.service

sudo vim /etc/systemd/system/usbmount@.service

内容如下:

    [Unit]
    BindTo=%i.device
    After=%i.device

    [Service]
    Type=oneshot
    TimeoutStartSec=0
    Environment=DEVNAME=%I
    ExecStart=/usr/share/usbmount/usbmount add
    RemainAfterExit=yes

现在就可以完美实现ntfs格式usb挂载

注意: udev的rules运行于独立的文件空间上,与用户的文件空间不同,因此及时挂载上了,用户也无法访问。因此需要将udev的运行方式改为共享。不然到时候无法自动卸载usb设备。
修改方式如下:

	vim /lib/systemd/system/systemd-udevd.service
	// 修改
	MountFlags=shared 

版权声明:本文为str125757855原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。