Linux通用udev系统启动及插入拔出U盘自动挂载卸载脚本及问题解决
sudo fdisk -l可以查看当前插入的usb sd或者cf外设
$sudo vi /etc/udev/rules.d/010.rules
======================================================
###########---USB---################
#----------------------------------#
KERNEL=="sd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="/etc/udev/rules.d/010.sh usb %k"
KERNEL=="sd[a-z]*", SUBSYSTEM=="block", ACTION=="remove", RUN+="/etc/udev/rules.d/010.sh usb %k", OPTIONS="last_rule"
##########---CF card---#############
#----------------------------------#
KERNEL=="hd[a-z]*", SUBSYSTEM=="block", ACTION=="add", RUN+="/etc/udev/rules.d/010.sh cf %k"
KERNEL=="hd[a-z]*", SUBSYSTEM=="block", ACTION=="remove", RUN+="/etc/udev/rules.d/010.sh cf %k", OPTIONS="last_rule"
#########-----SD------##############
#----------------------------------#
KERNEL=="mmcblk[0-9]*", SUBSYSTEM=="block", ACTION=="add", RUN+="/etc/udev/rules.d/010.sh sd %k"
KERNEL=="mmcblk[0-9]*", SUBSYSTEM=="block", ACTION=="remove", RUN+="/etc/udev/rules.d/010.sh sd %k", OPTIONS="last_rule"
======================================================
$sudo vi /etc/udev/rules.d/010.sh
======================================================
#!/bin/bash
#一般U盘插入之后会在/dev下产生一个sda和一个sda1节点,
#但是只有sda1是可以挂载的。sda是设备,sda1是分区
#有的U盘只会产生一个/dev/sda节点,此时就应该挂载sda。
#这个脚本不区分设备节点和分区节点,一律先挂载,
#但是挂载失败之后会立即清除建立的挂载点
#-------------------------------------------------#
#磁盘种类 设备节点 设备分区节点
#U盘 sd[a-z] sd[a-z][0-9]
#SD卡 mmcblk[0-9] mmcblk[0-9]p[0-9]
#CF卡 hd[a-z] hd[a-z][0-9]
#-------------------------------------------------#
#说明:在这个脚本中的可以把udev脚本的ACTION作为环境变量来用,
#但是无法使用KERNEL
#-------------------------------------------------#
if [ $# -ne 2 ] ; then #输入参数必须是两个
exit 1
fi
MNT_PATH=/media/pi/ #挂载移动设备的目录
DEV_PRE=$1 #参数1:挂载点的前缀
DEV_NAME=$2 #参数2:设备在/dev下的名字
FS_TYPE=vfat #设备的文件系统类型
if [ $ACTION == "add" ] ; then
#设备插入
#echo "=======add==========" >> /media/udev.txt
#echo "/bin/mkdir -p $MNT_PATH$DEV_NAME">>/media/udev.txt
sudo /bin/mkdir -p $MNT_PATH$DEV_NAME
sudo /bin/mount /dev/$DEV_NAME $MNT_PATH$DEV_NAME >& /dev/null
#echo "sudo /bin/mount /dev/$DEV_NAME $MNT_PATH$DEV_NAME >& /dev/null $?" >> /media/udev.txt
if [[ $? -ne 0 ]] ; then #mount失败则清除刚刚建立的目录
#echo "mount $DEV_NAME fialed" >> /media/udev.txt
sudo /bin/rmdir $MNT_PATH$DEV_NAME
fi
elif [ $ACTION == "remove" ] ; then
#设备移除
#echo "=======remove==========" >> /media/udev.txt
if [[ -e $MNT_PATH$DEV_NAME ]] ; then
sudo /bin/umount -l $MNT_PATH$DEV_NAME >& /dev/null
sudo /bin/rmdir $MNT_PATH$DEV_NAME
fi
fi
exit 0
======================================================
$sudo chmod +x /etc/udev/rules.d/010.sh
$sudo udevadm control --reload
以上步骤操作完,正常就可以实时检测到U盘的插拔事件,但你可能会发现,挂载成功了,但是数据却无法访问,此时需要做下一步配置:
$sudo vi /usr/lib/systemd/system/systemd-udevd.service
修改PrivateMounts=yes为PrivateMounts=no,保存.
(部分文章讲到MountFlags修改为shared,保存.请根据您实际情况进行修改配置测试)
$sudo reboot
(
或者手动重启systemd 和 udev进程服务:
sudo systemctl daemon-reload
sudo service systemd-udevd --full-restart
)
优化后的自动挂载方案:
sudo vi /etc/udev/rules.d/10-usbstorage.rules
============================================================
KERNEL!="sd*", GOTO="media_by_label_auto_mount_end"
SUBSYSTEM!="block",GOTO="media_by_label_auto_mount_end"
IMPORT{program}="/sbin/blkid -o udev -p %N"
ENV{ID_FS_TYPE}=="", GOTO="media_by_label_auto_mount_end"
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="Untitled-%k"
ACTION=="add", ENV{mount_options}="relatime,sync"
ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="iocharset=utf8,umask=000"
ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="iocharset=utf8,umask=000"
ACTION=="add", RUN+="/bin/mkdir -p /media/pi/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/pi/%E{dir_name}"
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/pi/%E{dir_name}", RUN+="/bin/rmdir /media/pi/%E{dir_name}"
LABEL="media_by_label_auto_mount_end"
=============================================================
保存退出,再次插入usb存储设备会自动挂载到/media目录下面的目录 并且支持utf8格式的中文文件名。