6.Linux的U盘自动挂载

Linux作服务器系统时,客户端常常要定位到服务器某个目录进行访问里面的网页或其它文件资源,那么如何做到客户端访问到服务器的USB设备(如U盘)呢?

显然需要在U盘等USB设备插到主板后,自动将其挂载到被访问目录,那如何实现?

有两种方式可以实现,一种是用udev服务来管理USB设备(以U盘为例),一种是自写脚本,通过不断刷描/dev/sda*里面U盘端口是否存在,以确定U盘已经插入,然后执行挂载。通常采用udev服务来实现自动挂载,因为udev服务在很多系统都是预安装的。

udev服务来实现自动挂载

1.原理:当驱动程序检测到USB设备插入、拔出、读写时,内核会发送uevent事件,udev服务监听这个事件。当udev监听到event,会在规则目录(系统规则目录:/lib/udev/rules.d/,用户规则目录:/etc/udev/rules.d/)下匹配所有规则文件(按开头数据编号优先级),匹配到含有uevent相应设备时,就执行规则后面的RUN,通常是启动了一个服务或脚本,达到检测到USB设备执行相应功能的目的。

2.根据原理,要实现自动挂载,需要三步:一是写一个执行脚本(实现挂载功能),二是写一个服务配置文件,服务执行的就是这个脚本,三是编写规则文件,使之能匹配到我们想要的USB设备(U盘)的拔插读写。

3. 与U盘挂载相关命令

        udevadm monitor  #监控USB插入或拔出,并将信息打印到终端

        lsblk #查看当前所有挂载设备情况

        mount [-t auto] [-o uid=pi] [-o pid=pi] [-o iocharset=utf8] [dev] [mountdir] #将dev挂载到mountdir下

        umount [dev] #取消挂载设备

4.写一个执行脚本,就是检测到USB设备插入或拔出,挂载这个设备到指定目录,将脚本改权限可执行:sudo chmod a+x xy_mount(本脚本不带后缀.sh是为方便调用时,可以像命令那样直接写名字即可),并将其保存在/usr/bin目录下,以方便调用

#!/usr/bin/bash

logfile=/home/biqu/printer_data/logs/usb_log
user=biqu
group=biqu
mountdir=/home/biqu/printer_data/gcodes/usb

[[ ! -e $logfile ]] && {
        touch $logfile
}
logi() {
        echo $1 >> $logfile
}
#权限检查
[[ `id -u` != 0 ]] && {
        logi "Error:current tool need root permission"
        exit 1
}

#参数检查
[[ ! $1 ]] && {
        logi "Error: need one parameter to signate the usb-device"
        exit 1
}
dev=/dev/${1##*/}

[[ ! -b $dev ]] && {
        if grep /etc/mtab -qe "^$dev"; then
                logi "$dev device already removed, so umount and clear media"
                if umount $dev;then
                        exitcode=0
                else
                        exitcode=$?
                        logi "Error: umount $dev errorcode:$exitcode"
                fi
        else
                exitcode=0
                logi "Device doesn't exist anymore or not a block device:$dev"
        fi
        #删除挂载点
        rm -rf $mountdir
        exit $exitcode
}

#使用blkid读取更多设备信息,eval将信息加进脚本
eval $(blkid -po export $dev)

[[ -z $TYPE ]] && {
        logi "$dev has no known filesystem type, ignring mount request"
        exit 0
}

#创建挂载点,并挂载设备到挂载点上
logi "Mount-dir:$mountdir,dev:$dev"
mkdir -p $mountdir
#必须加iocharset,不然有些系统可能挂上去文件名显示不正常
if mount -t auto -o uid=$user -o gid=$group -o iocharset=utf8 $dev $mountdir;then
        username="$(ps au | awk '$11 ~/^xinit/ {print $1;exit}')"
        [ $username ] && DISPLAY=:0 runuser -u $username xdg-open $mountdir
        logi "Device successfully mounted:$mountdir"
        exit 0
fi
logi "Error: mount-result:$?"
rm -rf $mountdir
exit 1

5.编写服务配置文件,以使udev可以以服务形式启动挂载脚本

[Unit]
Description=An usb device auto mount

[Service]
Type=forking
GuessMainPID=no
ExecStart=/usr/bin/xy_mount %I

6.编写规则

        6.1 udev规则目录有两个:/lib/udev/rules.d/和/etc/udev/rules.d/,前者是linux默认规则目录,一般不要去改动,后者是为用户提供的规则目录,因此,主要是在后面这个目录中加入规则

        6.2 进入规则目录后,新增规则目录文件,如:touch 60-my.rules,文件名以数字开头,数字越小,优先级越高;以.rules结尾;中间的名字可以任意取

        6.3编辑规则文件,文件中以#号开头表示注释,不会被匹配
                KERNEL用于匹配内核设备名称,通常设备插入会出现在/dev/下面,如/dev/sda1
                SUBSYSTEM,ACTION等都是匹配udevadm monitor中对应的属性名称的,其中最重要的ACTION,指示当前是add,remove等动作
                RUN则是匹配到了,该执行什么操作,这里是启动上面的服务

#mount the device when added
KERNEL=="sd[a-z]*",    SUBSYSTEM=="block",    ACTION=="add",    RUN+="/bin/systemctl --no-block restart yusb@%k.service"

#clean up after removal
KERNEL=="sd[a-z]*",    SUBSYSTEM=="block",    ACTION=="remove",    RUN+="/bin/systemctl --no-block restart yusb@%k.service"

注意:systemctl使用绝对路径,需要查看systemctl在哪个目录(which systemctl),有些系统是在/usr/bin下面,有些是在/bin下面,相应的,规则文件中的systemctl路径也要作改变

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值