複数のファイルのダウンロードが完了するまで待ちます。

複数のファイルのダウンロードが完了するまで待ちます。

フォルダにファイルが存在し、ファイルが安定していることを確認するための次のスクリプトがあります(これは私が受け取る大容量のビデオファイルについてです)。

#!/bin/bash

cdate1=$(date +%Y%m%d-%T)
folder1="/path-to-folder"

cd $folder1

while file=$(ls "$folder1")
      [ -z "$file" ]
        do sleep 10
        done
            echo "There is a file in the folder at $cdate1"
            size1=$(stat -c '%s' "$file")
            echo "The size1 is $size1"
            sleep 30
            size2=$(stat -c '%s' "$file")
            echo "The size2 is $size2"
        if [ $size1 = $size2 ]
        then
            ls -l
            echo "Start converting"
        else 
            echo "Restart the script"
        fi

同じフォルダ内の複数のファイルを確認し、すべてのファイルが安定したら変換スクリプトを起動するようにスクリプトを変更するにはどうすればよいですか?

ベストアンサー1

スクリプトには次のようないくつかの問題があります。

folder1="path-to-folder"
cd $folder1
while file=$(ls "$folder1") ...

本当ですcd path-to-folder; ls path-to-folderpath-to-folder絶対パス(例のように「/」で始まる)の場合は機能できますが、相対パスを使用している限りは機能しません。また、スペースが含まれていても機能しませんpath-to-folder。たとえば、どこでも引用符を使用する必要があるためです。cd "$folder1"

その後、aを実行すると常に次に設定され、無限while file=$(ls ...)ループが実行されます。file(ディレクトリの内容)。

正しい構文は、for file in $(ls ...)ファイル名にスペースが含まれていると動作を停止することです(名前がファイルの場合はfooループが実行されるため)。なぜ必要なのかを確認してくださいbarfoo barlsの出力を解析しないでください。。を使用する代わりに、ls単にfor file in *

最後に、ファイルサイズが変更されなくなってもファイルが変更される可能性があります。

ファイルを繰り返す良い方法は、findファイルが変更されたことを確認するための良い方法ですmtime

次の関数は、特定のディレクトリにあるすべてのファイルの最後の変更時刻(mtime)値を提供します。

folder1="/path-to-folder"
find "${folder1}" -exec stat -c "%Y" \{\} \;    \
   | sort -n | tail -1

したがって、スクリプトは次のようになります。

#!/bin/bash
dir="$1"
# check whether $dir exists
test -d "${dir}" || exit 1

last=0
current=1

while [ "$last" != "$current" ]; do
   last=$current
   current=$(find "${dir}" -exec stat -c "%Y" \{\} \; \
             | sort -n | tail -1)
   sleep 10
done
echo "directory is now stable..."

修正する

より良いアプローチは、特定のファイルが送信されたことを受信者に事前に通知することです。非常に簡単な解決策は、ペイロードが送信された後に空のダミーファイルをコピーすることです。たとえば、foo.avi「別のファイルをコピー」というファイルの場合は、そのファイルが準備されていることを確認するfoo.avi.copyfinishedだけです。foo.avi.copyfinishedfoo.avi

while true; do
 for file_ready in *.copyfinished; do
   file=${file_ready%.copyfinished}
   if [ -e "${file}.converted" ]; then
      echo "skipping already converted file ${file}" 1>&2
   else
      touch "${file}.converted"
      do_convert "${file}"
   fi
 done
 sleep 1
done

この解決策には明らかに発信者の協力が必要です。

おすすめ記事