udev ルールで実行すると、スクリプトの dd コマンドは実行されません。

udev ルールで実行すると、スクリプトの dd コマンドは実行されません。

ディスクが接続されているディスクステーションに接続されているときにDVDディスクを自動的にコピーするようにRasbianを実行するRaspberry Pi 3を設定したいと思います。これを達成するために、このルールがトリガーされたときに実行される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スクリプトは多少制限された環境で実行され、実行されます。

したがって、正しいアプローチは、ユーザーが起動したプログラム(D-Bus、ソケット、名前付きパイプ、またはその他の手段を介して)を起動し、そのプログラムがDVDを順番にコピーできるudevルールを作成することです。これはまた、DVDコピープログラムに適切な権限を付与する問題を解決します。

答え2

スクリプトやプログラムが期待どおりに機能しない場合は、デバッグツールが必要です。スクリプトの上部に次の2行を追加して、実行中の操作を文書化します。

set -x
exec >/tmp/debug-$$.out 2>&1

次に、実行された各コマンドのログを/tmp/ディレクトリのデバッグファイルに書き込みます。私の推測では、スクリプトが実行されないだけでなく、udevがスクリプトを実行するとDVDが表示されないため、次の行のコマンドも実行されないことがわかりddますejectwodimこの問題は、sleep以前に十分に追加することで解決できます。wodim.

関連情報