![运行 shell 脚本的 udev 规则在脚本进行到一半时有效,但未完成](https://linux22.com/image/176525/%E8%BF%90%E8%A1%8C%20shell%20%E8%84%9A%E6%9C%AC%E7%9A%84%20udev%20%E8%A7%84%E5%88%99%E5%9C%A8%E8%84%9A%E6%9C%AC%E8%BF%9B%E8%A1%8C%E5%88%B0%E4%B8%80%E5%8D%8A%E6%97%B6%E6%9C%89%E6%95%88%EF%BC%8C%E4%BD%86%E6%9C%AA%E5%AE%8C%E6%88%90.png)
我有一个 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 iteration
only.这意味着 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 或其他一些信号(尽管可能不需要)。