更新

更新

我试图在安装 USB 后在 USB 中创建一个文件夹。我正在使用下面的 udev 规则,我**ID_FS_UUID_ENC** (64AC6F22AC6EEE4C)作为参数发送,并start.sh在此路径中创建一个子文件夹 -/media/pi/64AC6F22AC6EEE4C

KERNEL!="sd[a-z][0-9]", GOTO="media_by_label_auto_mount_end"  
# Import FS infos  
IMPORT{program}="/sbin/blkid -o udev -p %N"
# Get a label if present, otherwise specify one  
#ENV{ID_FS_UUID_ENC}!="", ENV{dir_name}="%E{ID_FS_UUID_ENC}"  
#ENV{ID_FS_UUID_ENC}=="", ENV{dir_name}=""  
# Global mount options  
ACTION=="add", DRIVERS=="usb-storage", RUN+="/usr/bin/setsid /home/pi/raspberry-stilas/start.sh %E{ID_FS_UUID_ENC}"
ACTION=="add", DRIVERS=="usb-storage", RUN+="/bin/sh -c 'echo == >> /home/pi/raspberry-stilas/usb-storage-env.log; env >> /home/pi/raspberry-stilas/usb-storage-env.log'"
# Exit  
LABEL="media_by_label_auto_mount_end"

现在的问题是,当我插入 USB 时,start.sh会创建一个新文件夹并重命名传递的文件夹。因此64AC6F22AC6EEE4C创建了一个新文件夹,并将 USB 标签重命名为64AC6F22AC6EEE4C1.谁能告诉我我做错了什么?是不是USB没有安装,我正在尝试创建文件夹?

更新

我检查了系统日志和自定义日志,看起来设备正在脚本执行后安装。有什么办法可以让我只在安装后运行。

Custom Log - Stilas Python program run at 2019-05-18 11:33:01 PM
Syslog - May 18 23:33:02 raspberrypi udisksd[725]: Mounted /dev/sda1 at /media/pi/64AC6F22AC6EEE4C1 on behalf of uid 1000

添加后登录sleep 5

May 19 01:33:40 raspberrypi kernel: [  944.893519] usb 1-1.2: USB disconnect, device number 8
May 19 01:33:42 raspberrypi kernel: [  947.749507] usb 1-1.2: new high-speed USB device number 9 using dwc_otg
May 19 01:33:43 raspberrypi kernel: [  947.880955] usb 1-1.2: New USB device found, idVendor=0781, idProduct=558a
May 19 01:33:43 raspberrypi kernel: [  947.880971] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
May 19 01:33:43 raspberrypi kernel: [  947.880980] usb 1-1.2: Product: Ultra
May 19 01:33:43 raspberrypi kernel: [  947.880988] usb 1-1.2: Manufacturer: SanDisk
May 19 01:33:43 raspberrypi kernel: [  947.880997] usb 1-1.2: SerialNumber: 4C530001270213117013
May 19 01:33:43 raspberrypi kernel: [  947.881806] usb-storage 1-1.2:1.0: USB Mass Storage device detected
May 19 01:33:43 raspberrypi kernel: [  947.882227] scsi host1: usb-storage 1-1.2:1.0
May 19 01:33:43 raspberrypi mtp-probe: checking bus 1, device 9: "/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2"
May 19 01:33:43 raspberrypi mtp-probe: bus: 1, device: 9 was not an MTP device
May 19 01:33:44 raspberrypi kernel: [  948.890623] scsi 1:0:0:0: Direct-Access     SanDisk  Ultra            1.00 PQ: 0 ANSI: 6
May 19 01:33:44 raspberrypi kernel: [  948.891609] sd 1:0:0:0: Attached scsi generic sg1 type 0
May 19 01:33:44 raspberrypi kernel: [  948.891730] sd 1:0:0:0: [sdb] 120127488 512-byte logical blocks: (61.5 GB/57.3 GiB)
May 19 01:33:44 raspberrypi kernel: [  948.892813] sd 1:0:0:0: [sdb] Write Protect is off
May 19 01:33:44 raspberrypi kernel: [  948.892828] sd 1:0:0:0: [sdb] Mode Sense: 43 00 00 00
May 19 01:33:44 raspberrypi kernel: [  948.893398] sd 1:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
May 19 01:33:44 raspberrypi kernel: [  948.902832]  sdb: sdb1
May 19 01:33:44 raspberrypi kernel: [  948.905690] sd 1:0:0:0: [sdb] Attached SCSI removable disk

开始.sh

#!/bin/sh
sleep 5
echo "Device Mounted on - `date +"%Y-%m-%d %r."` Path - /media/pi/{$1}" env >> /home/pi/raspberry-stilas/mount.log
if [ "$1" != "" ]; then
  echo "Stilas Python program run at `date +"%Y-%m-%d %r."` Path - /media/pi/{$1}" env >> /home/pi/raspberry-stilas/mount.log
  python3 /home/pi/raspberry-stilas/stilas/stilas.py "/media/pi/$1"
fi

答案1

假设第 2 行/home/pi/start.sh有一个 shebang(位于#!/bin/sh第一行),sleep 5并且设置了执行位 ( chmod +x /home/pi/start.sh)。

使用setsid,它会fork,这意味着脚本执行在后台执行。上述睡眠是为了让您的系统有时间挂载 USB 设备。 Udev 在安装设备之前不会等待脚本完成,setsid将立即返回并且设备应该快速安装。

ACTION=="add", DRIVERS=="usb-storage", RUN+="/usr/bin/setsid /home/pi/start.sh %E{ID_FS_UUID_ENC}"

编辑:udev 等待所有子进程,因此该进程必须创建自己的组。

确保/home/pi/start.sh具有以下标头:

#!/bin/sh
pgid_from_pid() {
    local pid=$1
    ps -o pgid= "$pid" 2>/dev/null | egrep -o "[0-9]+"
}

pid="$$"
if [ "$pid" != "$(pgid_from_pid $pid)" ]; then
    exec setsid "$(readlink -f "$0")" "$@"
fi
sleep 5

创建 init.sh 脚本:

#!/bin/sh
/home/pi/start.sh "$@"

我们结合以下 udev 规则:

ACTION=="add", DRIVERS=="usb-storage", RUN+="/bin/sh /home/pi/init.sh %E{ID_FS_UUID_ENC}"

答案2

我建议 fork 的答案将不再适用于较新的 udev 系统:

RUN
...
Starting daemons or other long running processes is not appropriate for
udev; the forked processes, detached or not, will be unconditionally killed
after the event handling has finished.

您可以使用通用的 systemd 服务来mount安装您的设备,您可以使用:sudo systemctl list-units -t mount找到您的设备的 systemd 安装,写下其名称。

然后,您创建一个名为/etc/systemd/system/your.service

[Unit] 
Description=My mount script trigger 
Requires=<whatever the command above returned>.mount 
After=<whatever the command above returned>.mount 

[Service] 
ExecStart=/home/pi/start.sh 

[Install] 
WantedBy=<whatever the command above returned>.mount 

优点: 易于设置

缺点:仅适用于具有特定名称的 USB 设备。您必须自己在脚本中计算出 UUID。

答案3

需要实现一个对插入的 USB 闪存驱动器(插入自主 BBB 设备)做出反应的东西 - 获取设备名称,在那里挂载文件系统,rsync 东西到它,卸载。

为了避免任何并发问题(即并行地与设备发生冲突的多个问题)、正确的错误日志记录和其他启动问题,最明显的事情是将脚本包装在 systemd oneshot 服务中。

对我来说,唯一不立即明显的问题是如何将设备正确地传递给此类服务。

通过对谷歌结果进行一些挖掘(甚至在其中找到一篇文章),最终找到了“配对 udev 的 SYSTEMD_WANTS 和 systemd 的模板单元”解析线程,其中指定了似乎是当前最佳方法。

根据我的情况进行调整并与设备实例化服务的通用模式配对,得到以下配置。

udev规则:

ACTION=="add", PROGRAM="/usr/bin/systemd-escape -p [email protected] %E{ID_FS_UUID_ENC}", ENV{SYSTEMD_WANTS}+="%c"

[电子邮件受保护]:

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

[Service]
Type=oneshot
TimeoutStartSec=300
ExecStart=/home/pi/raspberry-stilas/start.sh /%I

改编自这里

相关内容