【发布时间】:2019-02-09 15:43:41
【问题描述】:
我尝试运行一个脚本来通过检查它的标签来识别 USB 密钥,并且它还有一个包含标识符的文件。我首先受到这个启发 -> Script not working when evoked by udev rule
这里首先是 udev 规则。它可以正常工作并正确调用我的脚本。
KERNEL=="sd[b-z]1", SUBSYSTEM=="block", ACTION=="add", GROUP="plugdev", OWNER="tuxin", RUN+="/home/tuxin/insert-usbkey.sh %k"
这是一个脚本,简化为最简单的表达式,用于测试操作。
#!/bin/bash
exec </dev/null >/tmp/key-inserted.log 2>&1; PS4=':$LINENO+'; set -x
KEY_LABEL="DEV_JP"
cd /media/tuxin || exit
(
for ((retries=0; retries<10; retries++)); do
[[ -d "$KEY_LABEL" ]] && grep -q -e "$KEY_LABEL" /proc/mounts && continue
sleep 1
done
cd "$KEY_LABEL" || exit
echo "SUCCESS"
) &
很遗憾,尽管挂载了密钥,但“SUCCESS”从未写入日志文件,其内容为:
:4+KEY_LABEL=DEV_JP
:6+cd /media/tuxin
:8+(( retries=0 ))
:8+(( retries<10 ))
:9+[[ -d DEV_JP ]]
:10+sleep 1
我们可以看到,在 'sleep' 命令之后,没有执行任何其他操作。通过多次测试,我得出的结论是,我的脚本在挂载密钥后立即停止,并且在挂载密钥时我无法执行任何操作。
所以我继续我的研究并关注了这个讨论 -> how to execute a script every time any USB get mounted
所以我制定了以下规则,我理解起来有点麻烦,但结果完全一样:
KERNEL!="sd[a-z]*", GOTO="media_by_label_auto_mount_end" ACTION=="add", PROGRAM!="/sbin/blkid %N", GOTO="media_by_label_auto_mount_end"
# Get label
PROGRAM=="/sbin/blkid -o value -s LABEL %N", ENV{dir_name}="%c"
# use basename to correctly handle labels such as ../mnt/foo
PROGRAM=="/usr/bin/basename '%E{dir_name}'", ENV{dir_name}="%c" ENV{dir_name}=="", ENV{dir_name}="usbhd-%k"
ACTION=="add", ENV{dir_name}!="", RUN+="/bin/su tuxin -c '/usr/bin/pmount %N %E{dir_name}'", RUN+="/home/tuxin/insert-usbkey.sh"
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/su tuxin -c '/usr/bin/pumount /media/%E{dir_name}'"
LABEL="media_by_label_auto_mount_end"
脚本在手动启动时正常工作,但由 udev 执行,一旦安装密钥,在我看来它就被杀死了。在自动检测安装后,我该如何做我想做的事情?
这里是对该脚本进行测试的机器的摘要(有或没有后台操作)。为什么这在 Linux Mint 中不起作用还有待理解。
Distribution udev version Result
-------------------------------------
Linux Mint 18 229 KO
L.M.D.E. 215 OK
Poky custom. 182 OK
Linux Mint 18 229 KO
Lubuntu 18.04 237 OK
【问题讨论】:
-
我不能告诉你,但是对于一个写得很好的问题 +1。
-
很奇怪。如何添加一些陷阱来检测它是否被发送信号,并重定向到
/tmp/key-inserted.log.$$以确保文件不会被另一个实例截断 -
我将 udev 日志置于“调试”模式:
udevadm control --log-priority=debug,我的脚本只有一个调用。