USBフラッシュドライブの挿入を検出したら、RPi 2(MiniBian
最小バージョンのDebianベースのOSを使用)をオペレーティングシステムとして使用してスクリプトを実行したいと思います。Raspbian
これが私がしたことです:
私は/etc/udev/rules.d/10-usbstick.rules
次の内容でこれを作りました:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*" SYMLINK+="usbflash", RUN+="/path/to/myscript.sh"
次に、/path/to/myscript.sh
次の内容にします。
#!/bin/bash
mount /dev/usbflash /mnt/
service omxd stop
rm -r /path/to/myfolder/*
cp -f /mnt/*.mp4 /path/to/myfolder/
cp -f /mnt/*.avi /path/to/myfolder/
sleep 1
umount /dev/usbflash
halt
USBフラッシュドライブを挿入すると、それを認識してマウントし、デーモンを停止し、古いomxd
ファイルをすべて削除します。
しかし、問題は、halt
すべてのファイルをコピーする前に終了することです()。後で確認してみるとファイルが1つだけコピーされたのですが、halt
コピー過程で命令を実行したかのように正しくコピーされていませんでした。
したがって、コマンドが最後にのみ実行されるwait
ようにコマンドを使用することにしました。ファイルを次のように編集しましたhalt
。/path/to/myscript.sh
#!/bin/bash
mount /dev/usbflash /mnt/
PID1 = $!
wait PID1
service omxd stop
rm -r /path/to/myfolder/*
PID2 = $!
wait PID2
cp -f /mnt/*.mp4 /path/to/myfolder/
PID3 = $!
wait PID3
cp -f /mnt/*.avi /path/to/myfolder/
PID4 = $!
wait PID4
sleep 1
umount /dev/usbflash
PID5 = $!
wait PID5
halt
しかし、同じことが再び発生しました。コピー処理中にシステムが停止しました。
それでは、私のシステムに何が問題なのでしょうか?
システムに通知するにはどうすればよいですか?halt
その後すべての新しいファイルが正常にコピーされました! ?
アップデート1
sync
以前に追加しましたがumount
効果halt
はありません。同じシーンがまた起こりました。
アップデート2
/path/to/myscript.sh
ファイルを次のように編集しました。
mkdir -p /mnt/usb
if mount /dev/usbflash /mnt/usb
then
service omxd stop
rm -r /path/to/myfolder/*
cp -f /mnt/usb/*.mp4 /path/to/myfolder/
cp -f /mnt/usb/*.avi /path/to/myfolder/
sync
umount /mnt/usb
sync
shutdown -h now
fi
しかし、それも役に立ちません!同じシーンがまた出ましたね!今回ははるかに悪いです。ファイルをまったくコピーしません!
アップデート3
私はそれを/etc/udev/rules.d/10-usbstick.rules
次のように変更しました:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/path/to/myscript.sh"
今はうまくいきます。すべてのファイルをコピーします。しかし、新しい問題があります。ドラッグできません!
アップデート4
私は新しいものを見つけました:
端末で直接実行するmyscript.sh
とうまく機能します。古いファイルを削除し、新しいファイルをコピーしてシステムをシャットダウンします。完璧。
myscript.sh
それでは、udevルールから呼び出すと、なぜ完全に実行されないのですか?
ファイルのコピー後にシステムをシャットダウンする他の方法はありますか? ?
答え1
wait
for コマンドは、バックグラウンドで実行されない限り意味がありません。おそらく欠けているのは、sync
すべての書き込みをメディアに強制的に適用することです。ただし、これはumount
コマンドの一部として発生する必要があります。
この単純化されたスクリプトが必要に応じて動作することを確認したいと思います。
#!/bin/bash
#
export PATH=/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin
mkdir -p /mnt/usb
if mount /dev/usbflash /mnt/usb
then
service omxd stop
rm -r /path/to/myfolder/*
cp -f /mnt/usb/*.mp4 /path/to/myfolder/
cp -f /mnt/usb/*.avi /path/to/myfolder/
sync
umount /mnt/usb
sync
shutdown -h now
fi
あなたの説明がUSBスティックのファイルを更新したいことを示しているようで、少し混乱していることを認めなければなりません。しかし、コードはファイルを更新します。/path/to/my/folder
~から書き込みの代わりにUSBスティック/mnt/usb/...
答え2
カーネルの名前を変更すると、なぜ影響を与えるのかわかりませんが(おそらくsd*1
タスクを完了するのに多くの時間を許可した後に実行されますか?)、udevはイベントで長期実行タスクを好まない。sd*
デーモンや他の長期実行プロセスを開始することはudevには適していません。切り離されたかどうかにかかわらず、分岐されたプロセスはイベント処理が完了した後に無条件に終了します。
元nohup
の提案
私は最初にnohup
私のリンクを完全に読む前に提案しました。 :) - これは実際には動作しない可能性があることを示します。
udevルール:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/path/to/mywrapper.sh"
mywrapper.sh
(注:出力をリダイレクトしないと、nohupはディレクトリにファイルを分散させることができますnohup.out
):
#!/bin/sh
nohup /path/to/myscript.sh >/log/myscript.log 2>&1 &
だとしたらmyscript.sh
大丈夫です。
最新のsystemd
提案
以下の3番目のリンクは、デバイスが接続されているときにsystemdサービスをオフにすることを示しています。このブログエントリは、デバイス情報がサービスに配信されることを確認するために必要であると考えるよりも多くの作業を実行するため、考える単純にsystemdをデーモンメソッドとして使用できます。
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]1" SYMLINK+="usbflash", RUN+="/usr/bin/systemctl start my-usb-backup.service"
簡単なワンタイムサービスでmy-usb-backup.service
:
[Unit]
Description=run myscript
[Service]
Type=oneshot
ExecStart=/path/to/myscript.sh
また見なさい: