udevはスクリプトの動作に影響を与え、dpkgが機能しなくなる


2

USBフラッシュドライブが挿入されるたびにシェルスクリプトを実行するように設定されたudevルールがあります。 udevがルールと一致すること、シェルスクリプトが正しいパラメータで手動で実行されたときに意図したとおりに実行されること、およびスクリプトが実行されていることを確認しました。これでドライブは正常にマウントされ、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

回答:


0

それ以外の部分についてはよくわかりませんが、空のファイルが表示されるのは、スクリプトに構文エラーがあるためです。

#!/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


私の知る限り、udevはすべてをrootとして実行します。たとえばマウントは機能しています。そして、チルダはタイプミスです、それがそこに入った方法がわからない。
tacoman

@MaxGeneはい私はそれをしたと想像しました、しかし、私はそれが他の種類の特権ユーザーとして動く場合に備えて私が尋ねたいと思いました。主なエラーは `ではなく`でした &。あなたがそれを私が提案したものに変更するならば、あなたは少なくともいくつかの有益なエラーメッセージを得て、それをデバッグすることができるべきです。
terdon

@MaxGeneはここで暗闇の中で撃った、しかしあなたがVFATドライブをマウントしているならばあなたは入っていないかもしれない if VFATは大文字と小文字を区別しないのでループします。それがどのように影響するかはわかりませんが、特定のファイル名を指定しているため、問題になる可能性があります。変更してみてください if [-f のように if [ $(find /media/${ID_FS_LABEL}/ -iname ACS.deb) ]
terdon

実際には今では完全に機能しています。私はあなた自身を補足するために私自身の質問に対する答えをまだ投稿することはできませんが、他の問題(私が出力リダイレクトを修正した後に私が発見した)はどういうわけかスクリプトからの私自身のパスの設定とエクスポートはうまくいきました。
tacoman

@MaxGeneああ、いいですね。あなたはあなた自身の質問に対する答えを投稿することができ、そして実際に投稿すべきです。あれは 積極的に励ました SEサイトで。私はあなたが私の答えを受け入れないことをお勧めします。
terdon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.