我尝试运行一个脚本,通过检查其标签来识别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
答案 0 :(得分:0)
您的测试脚本在后台子shell 中运行其主要逻辑。因此,它在启动子Shell之后几乎立即完成,因此父bash进程会忠实地向所有子进程发出信号,并在其无能为力之前将其杀死。
不需要背景和子外壳;以下代码可以在我的系统上与udev完美配合:
#!/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 && break
sleep 1
done
cd "$KEY_LABEL" || exit
ls . # Double-check by listing the drive's contents
echo "SUCCESS"
还请注意,我将您的continue
更改为break
,因为当您找到所需的内容时,这正是您想要做的:突破循环。