参考 用脚本实现U盘的自动挂载
板子是用的debian,插上U盘时会自动挂载U盘到
/media/root/
下,还自动弹出窗口,需求是想换个地方,不弹窗,名字固定下来,所以才想到自己更改配置文件。
查了下板子上的debian的文件系统使用的动态设备管理工具是udev,(mdev是udev的精简版,适用于嵌入式的)。
背景知识
man udev看了看,
udev的配置在/etc/udev下,udev有两类文件,
-
1.Configuration file
-
/etc/udev/udev.conf
—main configuration file ,不用改动
2.Rules files
- 顾名思义,就是定义匹配规则的文件,udev依照这些文件的匹配执行相应程序,该文件必须以**.rules**结尾,其它结尾的会被无视,规则分别位于三个目录下:
-
default rules directory
/lib/udev/rules.d/
-
the custom rules directory
/etc/udev/rules.d/
-
the temporary rules directory
/run/udev/rules.d/
所有rules文件(无论在哪个目录下)依lexical order规则(由小到大)优先执行,同名文件,优先权:/etc/ > /run >/lib ,
其它具体自己找man吧,这里以u盘说明
U盘自动挂载操作
-
step 1. 在**/etc/udev/rules.d/**下新建U盘加载规则文件,数字小点为了覆盖掉原来的规则,也可以自己找到原本的U盘加载规则文件,我是没找到放弃。 中间名字任取,结尾一定要以.rules结束。如:
10-usbdisk.rules
,内容如下KERNEL=="sd[a-e]*", SUBSYSTEM=="block", RUN+="/path/to/script.sh"
规则文件每一行都至少有一对
key-value
,多对用**","**分隔,
key==value:指条件相等的match,
key+=value:KEY中添加值。KERNEL
Match the name of the event device.SUBSYSTEM
Match the subsystem of the event device.RUN
Add a program to the list of programs to be executed for a specific device.
ACTION
Match the name of the event action.DEVPATH
Match the devpath of the event device.查询key,value及测试rules可用udevadm 命令如下
udevadm info -p /sys/devices/system/cpu/cpu0/ -a
-
step 2. 写匹配后的执行脚本script.sh,放置到上述指定的绝对路径中,相对路径默认通常是**/lib/udev/**,脚本内容如下:
#!/bin/sh # log日志 LOG=/var/log/usb-hotplug.log logtime=$(date) # 挂载位置 MDIR=/mnt/udisk echo "$logtime:$DEVPATH requesting $ACTION" >> $LOG if [ "$ACTION" = "add" ]; then if [ ! -d $MDIR ]; then echo "the $MDIR is not exist,mkdir" >>$LOG mkdir -p $MDIR fi mount $DEVNAME $MDIR echo "$logtime:mount $DEVNAME $MDIR" >> $LOG elif [ "$ACTION" = "remove" ]; then umount $MDIR rmdir $MDIR echo "$logtime:umount $DEVNAME -$ACTION" >> $LOG fi
-
step 3 注意脚本加上执行权限,
chmod a+x path/to/script
,基本上就OK了,不需要重启机子,如果不行再重启试试吧。
u盘强拔后的保存问题
linux下在没有umount时直接拔出U盘,会使得写入U盘的数据消失。度娘了下U盘拔出注意事项
注意事项:
- 如果不卸载直接拔,可能让正在使用文件的进程崩溃。
- 如果正在写入,直接拔会损坏文件,严重者会损坏闪存。
- linux有写入缓存机制(将需要写入到磁盘的数据先在内存中缓存起来,在合适的时候才真正写入到磁盘中,用以提高磁盘操作效率),直接拔会让看似写入完毕的文件消失。
因此:
- 拔出U盘前必需先umount /dir
- 拔出U盘后,确保删除mount目录,检查下**/dev/sd***之类设备是否自删了。
所以回头看脚本中的自动卸载发生的太迟了点。等你拔出U盘时,umount那条命令以经没意义了,所以无法保存写入的数据 ,只能做做扫尾工作了(删除mount 目录)。
那如何在直接拔U前数据能保存进去呢?
测试了下使用sync函数可行。每次保存数据后跟着执行一次发现直接拔除也能保存了。也可以在确定要拔出前执行一次就好。
sync作用就是强制将有改变的blocks块内容写到磁盘,更新super blocks.
后续 疑惑:
debian下将挂载位置弄到/media/下,总是自动弹窗,在/mnt位置就没有这现象,看来d-bus还有其它操作了。