新しいファイルが表示されたら、すぐにデータをUSBキーに同期する非常に単純なbashスクリプトがあります。うまく書かれていませんが、うまくいきますが、CPU時間を最小限に抑えたかったので、sleep
inotifywaitを同期トリガーとして使用しているため、スクリプトは追加された新しいファイルごとに1秒のスリープモードを追加します(小さなファイルがたくさんあります)。私の解決策は、read
inotifywait出力の最新の行だけを読むことです。 tail -1でパイピングして実行したいのですが、うまくいかないようです。
#!/bin/bash
watched_path=".wine/drive_c/Data"
rm -r "$HOME/$watched_path/"*
inotifywait -r -m "$HOME/$watched_path" --format "%e %w%f" -e create -e moved_to |
while read action full_path; do
sleep 1
file=${full_path##*$watched_path}
echo "'$file' appeared in directory '$watched_path' via '$action'"
USB="USBKEY"
# Wait for USB to be connected before syncing.
until [ -e /media/$USER/$USB ]; do
echo "Connect USB for sync."
sleep 5
done
rsync -r "$HOME/$watched_path" /media/$USER/$USB
echo "Sync complete."
done
フォルダ全体を同期するため、inotifywaitを使用して1行を見逃しても問題はありませんが、読み取るときは最新のファイル(したがって最新の行)の後に同期する必要があります。これは、ファイル転送が中断された瞬間からwhileループが再び中断される前に最大1回実行されることを意味します。
どうやって読むことができますか?最新の行のみinotifywait出力?この問題を避けるための他の提案があれば大丈夫です。しかし、まだ答えに興味があります。
答え1
私はあなたが求めるのがより複雑なシナリオだと思います。 「最後」の到着ファイルを識別する方法を説明していないため、1つ以上のファイルが転送されたため、5秒間ファイルが無効になってからタイムアウトします。
- フラグ設定 = 待機
- パラレル:ファイルが通知を受け取るたびにフラグ= not_doneを設定します。
フラグ== not_doneになるまで待ちます。
ループ開始
- USB接続を待って同期処理を開始します(
rsync
)。 - 新しいファイルが転送されたら、フラグ= not_doneを設定します。
- そうでなければ
- フラグ==like_doneの場合はflag=determinly_doneを設定し、それ以外の場合はflag=like_doneを設定します。
- 5秒もかからない場合は、残り時間を待ってください。
- USB接続を待って同期処理を開始します(
- フラグ==define_doneまで繰り返す
メインプロセスとパラレルプロセスの間にIPCが必要なので、inotifywait
フラグをファイルとして実装するか、ファイル名のセットとして実装することを考えてみましょう。
私が知る限り簡単ではないrsync
新しいファイルが転送されたことを確認してください。前と後のターゲットディレクトリの内容を比較する必要があるかもしれません。