udev 影响脚本的行为,导致 dpkg 无法运行

udev 影响脚本的行为,导致 dpkg 无法运行

我配置了一条 udev 规则,只要插入 USB 闪存驱动器,就会运行一个 shell 脚本;我已验证 udev 是否​​符合规则,shell 脚本是否在使用正确的参数手动运行时按预期运行,以及脚本是否正在运行;它成功安装了驱动器并到达应该运行 dpkg 的地步,但实际上什么都没有安装。

同样让我感到沮丧的是,我将 dpkg 和脚本本身都设置为将其输出重定向到临时文件,以便我可以调试此问题;但是,虽然两者在手动运行时都能完美显示其输出,但在由 udev 触发时,它们会产生完全空的文件,因此我甚至看不到 dpkg 可能产生的错误,如果它确实产生了错误。我听说 udev 不使用终端运行程序,但我不知道是否是这种情况,或者这是否会导致这种情况。

udev 规则:

SUBSYSTEMS=="usb", KERNEL=="sd?1", RUN+="/usr/local/sbin/updater-runner.sh %"

由 udev 直接运行的脚本:

#!/bin/sh

/usr/local/sbin/updater.sh ${1} & > /tmp/updater.out`

主要脚本:

#!/bin/sh

DEVICE=$1
echo "Running..."
echo $DEVICE
# check input
if [ -z "$DEVICE" ]; then
    exit 1
fi

# test that the device isn't already mounted
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
    echo "error: seems /dev/${DEVICE} is already mounted"
fi

# pull in useful variables from vol_id, quote everything Just In Case
# eval `blkid /dev/${DEVICE} -o value | sed 's/^/export /; s/=/="/; s/$/"/'`

ID_FS_LABEL=$(blkid /dev/${DEVICE} -o value | head -n 1)
export ID_FS_LABEL
ID_FS_TYPE=$(blkid /dev/${DEVICE} -o value | tail -n 1)
export ID_FS_TYPE
echo $ID_FS_LABEL
echo $ID_FS_TYPE
if [ -z "$ID_FS_LABEL" ] || [ -z "$ID_FS_TYPE" ]; then
    echo "error: ID_FS_LABEL is empty! did vol_id break? tried /dev/${DEVICE}"
    exit 1
fi

# test mountpoint - it shouldn't exist
if [ ! -e "/media/${ID_FS_LABEL}" ]; then
    # make the mountpoint
    mkdir "/media/${ID_FS_LABEL}"

    # mount the device

    case "$ID_FS_TYPE" in

        vfat) mount -t vfat -o sync,noatime,uid=1000 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
            ;;

        ntfs) mount -t auto -o sync,noatime,uid=1000,locale=en_US.UTF-8 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
            ;;

        ext*) mount -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
            ;;
    esac

    #check if file exists

    #run dpkg
    if [ -f "/media/${ID_FS_LABEL}/ACS.deb" ]; then
        echo "Killing ACS..."
        killall ACS
        echo "Running dpkg..."
        yes | dpkg --force-architecture --force-depends -i "/media/${ID_FS_LABEL}/ACS.deb" > /tmp/dpkg.out
        echo "Restarting ACS..."
        nohup ACS &> /dev/null &
    fi
fi

exit 0

答案1

不确定其余部分,但您获取空文件的原因是您的脚本中存在语法错误:

#!/bin/sh

/usr/local/sbin/updater.sh ${1} & > /tmp/updater.out`

应该是(您还应该捕获 STDERR):

#!/bin/sh

/usr/local/sbin/updater.sh ${1} > /tmp/updater.out 2>/tmp/updater.error &

按照你的方式,脚本被放在后台不会生成任何输出,但您会得到空文件。另外,我假设行末的 ` 是拼写错误,对吗?

至于其余部分,这是以哪个用户身份运行的?我对 udev 了解不够,无法猜测。以谁的身份运行脚本是否有权执行dpkg

相关内容