コピープロセス(cp)が完了するのを待つ方法は?

コピープロセス(cp)が完了するのを待つ方法は?

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

waitfor コマンドは、バックグラウンドで実行されない限り意味がありません。おそらく欠けているのは、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

また見なさい:

関連情報