事实上Ubuntu是支持U盘自动挂载的,插上U盘它能自动识别并且多出一个盘符来。但我的应用设置了软件开机满屏自启动且跳过了桌面,所以就无法自动挂载了。
通过fdisk -l可以查看到U盘的设备名,如/dev/sda
通过sudo mount /dev/sda1 /mnt/usb也可以实现挂载,可通过df -h查看确认
以上是手动敲指令的方式,我们也可以通过fstab或udev的方式实现自动挂载。其中fstab的方式需要提前获知U盘的UUID参数,不太方便,因此下边只使用udev方式。
我们可以创建udev规则,用于在U盘插拔时自动触发一些动作。
首先进入/etc/udev/rules.d/,新建一个规则如99-usb-mount.rules,添加以下内容
ACTION=="add", SUBSYSTEMS=="usb", RUN+="/usr/local/bin/usb-mount.sh"
ACTION=="remove", SUBSYSTEMS=="usb", RUN+="/usr/local/bin/usb-umount.sh"
然后根据上述规则,我们进入/usr/local/bin,分别创建两个脚本usb-mount.sh和usb-umount.sh,内容如下
#!/bin/bash
MOUNT_POINT="/media/usb"
[ ! -d "$MOUNT_POINT" ] && mkdir -p "$MOUNT_POINT"
DEVICE_NAME=$(lsblk -o NAME,TRAN | grep usb | awk '{print $1}')
for device in $DEVICE_NAME; do
mount /dev/$device $MOUNT_POINT
done
#!/bin/bash
MOUNT_POINT="/media/usb"
umount $MOUNT_POINT
然后设置脚本可执行权限,然后重新加载udev规则即可生效。
sudo udevadm control --reload-rules
sudo udevadm trigger
对于不喜欢使用脚本的,也可以直接写一个程序,开机自启动即可。当然,程序本质上也是利用udev,需要安装libudev库。
首先安装sudo apt-get install libudev-dev
接下来是代码,新建usb_automount.c
#include <stdio.h>
#include <stdlib.h>
#include <libudev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#define MOUNT_DIR "/mnt/usb"
void mount_usb(const char *device) {
char command[256];
snprintf(command, sizeof(command), "sudo mkdir -p %s/%s", MOUNT_DIR, device);
system(command);
snprintf(command, sizeof(command), "sudo mount /dev/%s %s/%s", device, MOUNT_DIR, device);
if (system(command) == 0) {
printf("USB device /dev/%s mounted at %s/%s\n", device, MOUNT_DIR, device);
} else {
printf("Failed to mount /dev/%s\n", device);
}
}
void umount_usb(const char *device)
{
char command[256];
snprintf(command, sizeof(command), "sudo umount %s/%s", MOUNT_DIR, device);
if(system(command)==0)
{
printf("USB device /dev/%s unmounted\n", device);
}
else
{
printf("Failed to unmount /dev/%s\n", device);
}
}
int main() {
struct udev *udev;
struct udev_monitor *mon;
struct udev_device *dev;
udev = udev_new();
if (!udev) {
fprintf(stderr, "udev_new() failed\n");
return 1;
}
printf("usb monitor start\r\n");
mon = udev_monitor_new_from_netlink(udev, "udev");
if (!mon) {
fprintf(stderr, "udev_monitor_new_from_netlink() failed\n");
udev_unref(udev);
return 1;
}
udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "disk");
udev_monitor_enable_receiving(mon);
while (1) {
dev = udev_monitor_receive_device(mon);
if (dev) {
const char *action = udev_device_get_action(dev);
const char *devtype = udev_device_get_devtype(dev);
const char *devnode = udev_device_get_devnode(dev);
if (action && devtype && devnode && strcmp(devtype, "disk") == 0) {
if (strcmp(action, "add") == 0) {
const char *devname = strrchr(devnode, '/') + 1;
char newname[10];
strcpy(newname,devname);
strcat(newname,"1");
mount_usb(newname);
}
else if(strcmp(action, "remove") == 0)
{
const char *devname = strrchr(devnode, '/') + 1;
char newname[10];
strcpy(newname,devname);
strcat(newname,"1");
umount_usb(newname);
}
}
udev_device_unref(dev);
}
sleep(1);
}
udev_monitor_unref(mon);
udev_unref(udev);
return 0;
}
代码功能与脚本基本一致,仅挂载目录差别,不作赘述。
编译后执行即可测试,测试正常后添加到开机自启动即可。
gcc -o usb_automount usb_automount.c -ludev
sudo ./usb_automount