运行 shell 脚本的 udev 规则在脚本进行到一半时有效,但未完成

运行 shell 脚本的 udev 规则在脚本进行到一半时有效,但未完成

我有一个 udev 规则,它将运行 shell 脚本来创建目录并以只读模式挂载设备。问题是,当规则运行时(当我插入设备时),它会创建目录但不会挂载设备。

自然,剧本肯定有问题。但是,我可以运行该脚本(我插入设备,手动删除 udev 规则创建的目录,然后也手动运行该脚本),它会很好地创建目录并挂载设备。

udev 规则的相关部分(文件名 = '10-magicusb.rules'):

ENV{MYMOUNT}=="1", RUN+="/etc/udev/scripts/romount.sh"

romount.sh:

#!/bin/bash
mkdir /media/sdb1
/bin/mount /dev/sdb1 -o ro,noatime /media/sdb1

从技术上讲,设备名称来自 udev 规则的更上方(它不是硬编码的,相信我)。我运行一个创建的脚本romount.sh,并将该脚本传递给设备%k。但是,这不应该相关,因为脚本运行来自 udev,但在执行中途停止。

我的猜测是这里出现了一些时间问题。当规则运行时,由于某种原因它无法安装设备,但是当我稍后手动执行此操作时,我猜系统有时间来解决问题。我sleep 10在 bash 脚本的顶部添加了一个无济于事。

先感谢您。

编辑1

根据 David G. 发布的内容,我使用改进的脚本进行了一些测试,现在romount.sh看起来像这样:

#!/bin/bash
mkdir /media/sdb1
(
    echo 'before while iteration' > /etc/udev/scripts/iteration.txt
    while [[ ! -b /dev/sdb1 ]]
    do
        sleep 1
        echo 'iteration performed' > /etc/udev/scripts/iteration.txt
    done
    /bin/mount /dev/sdb1 -o ro,noatime /media/sdb1
) &

生成的iteration.txt文件有:before while iterationonly.这意味着 while 循环的条件永远不会被触发。这意味着设备节点在执行时可用,对吧?

编辑2

我终于让它与第二个答案一起工作:用于挂载磁盘的 Udev 规则不起作用

将 PrivateMounts=No 添加到 systemd-udevd.service 对我有用。

答案1

我怀疑问题在于该脚本是在创建设备节点之前运行的。尝试类似的方法(即没有硬编码):

#!/bin/bash
mkdir /media/sdb1
(
    while [[ ! -b /dev/sdb1 ]]
    do
        sleep 1
    done
    /bin/mount /dev/sdb1 -o ro,noatime /media/sdb1
) &

重要的部分是后台子shell。

根据 udev 的作用,您可能会遇到需要对 stdin、stdout 和 stderr 执行某些操作的问题。您可能还需要忽略 SIGHUP 或其他一些信号(尽管可能不需要)。

相关内容