我想设置一个运行 Rasbian 的 Raspberry Pi 3,以便在将磁盘插入耦合的磁盘站时自动复制 DVD 磁盘。为了实现这一点,我编写了一个 udevrule 和一个在触发此规则时运行的脚本。
udev 规则似乎工作正常,并在插入磁盘时运行脚本。
该脚本包含dd
命令。当我从命令行手动执行脚本时,它可以正常工作并执行命令dd
。udev
但是,当通过磁盘插入运行脚本时,脚本中的所有内容都会执行,但dd
命令除外。
我在网上搜索过,但找不到其他人有同样的问题。有人知道问题可能是什么吗?
udev规则/etc/udev/rules.d/65-autorip.rules
:
SUBSYSTEM=="block", KERNEL=="sr[0-4]", ACTION=="change", RUN+="/usr/local/bin/autorip/autorip.sh /dev/%k %E{ID_CDROM_MEDIA}"
磁盘复制脚本/usr/local/bin/autorip/autorip.sh
:
#!/bin/bash
# function to activate a led and eject disk when an error occurs
error(){
python /usr/local/bin/autorip/led-on.py
eject
}
# function to deactivate the led for
reset_led(){
python /usr/local/bin/autorip/led-off.py
}
# if udev flag to check if disk change action is insert (second script parameter) is set
if [ $2 == "1" ]; then
reset_led
#use wodim command to find out if disk is DVD
disk_info=$(wodim -atip dev='/dev/sr0')
if [[ $disk_info = *"mmc_mdvd"* ]] ; then
# copy disk contents to temp location (not working when ran from udev)
dd if=/dev/sr0 of=/tmp/autorip_disk_image_$RANDOM$RANDOM.iso
eject
else
error
fi
fi
答案1
udev
规则是不是适用于长时间运行的任务,例如复制 DVD。从man udev
:
这只能用于运行时间非常短的前台任务。长时间运行事件进程可能会阻止该设备或从属设备的所有进一步事件。
启动守护进程或其他长时间运行的进程不适合 udev;分叉的进程,无论是否分离,都将在事件处理完成后被无条件终止。
此外,通过udev
在某种程度受限的环境中运行来执行的脚本。
因此,正确的方法是制定一个 udev 规则来触发用户已经启动的程序(通过 D-Bus、套接字、命名管道或其他方式);然后该程序可以依次复制 DVD。这也解决了给予 DVD 复制程序适当权限的问题。
答案2
当脚本或程序没有执行您认为应该执行的操作时,就需要使用调试工具了。在脚本中,在顶部添加以下两行以记录其正在执行的操作:
set -x
exec >/tmp/debug-$$.out 2>&1
然后它会将执行的每个命令的日志写入 /tmp/ 目录中的调试文件。我的疯狂猜测是,您会看到脚本不仅不执行dd
,而且eject
下一行中的命令也不会执行,因为wodim
udev 运行脚本时该命令看不到 DVD。这可能可以通过sleep
在之前添加足够的内容来解决wodim.