Ich habe das folgende Skript, das überprüft, ob sich eine Datei in einem Ordner befindet und ob die Datei stabil ist (dies gilt für große Videodateien, die ich erhalte).
#!/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
Wie ändert man das Skript so, dass es mehrere Dateien im selben Ordner prüfen kann und nachdem alle stabil sind, um das Konvertierungsskript zu starten?
Akzeptierte Antwort:
Es gibt eine Reihe von Problemen in Ihrem Skript, beginnend mit:
folder1="path-to-folder"
cd $folder1
while file=$(ls "$folder1") ...
das tut wirklich cd path-to-folder; ls path-to-folder
; if path-to-folder
absolut ist (beginnend mit einem '/' wie in Ihrem Beispiel), könnte dies funktionieren, aber es funktioniert nicht, wenn Sie relative Pfade verwenden.
Es funktioniert auch nicht, wenn path-to-folder
enthält Leerzeichen, da Sie überall Anführungszeichen verwenden sollten, z. cd "$folder1"
dann mache ein while file=$(ls ...)
wird eine Endlosschleife ausführen, als file
wird immer auf etwas gesetzt (der Inhalt des Verzeichnisses).
die richtige Syntax wäre for file in $(ls ...)
, die nicht mehr funktioniert, sobald Sie Dateinamen mit Leerzeichen haben (da die Schleife auf foo
ausgeführt wird und bar
wenn Sie eine Datei namens foo bar
haben ). Überprüfen Sie, warum Sie die Ausgabe von ls niemals analysieren sollten. statt ls
zu verwenden Sie könnten einfach for file in *
ausführen .
Schließlich könnten Sie Dateien haben, die sich ändern, auch wenn sich ihre Größe nicht mehr ändert.
Eine gute Möglichkeit, Dateien zu durchlaufen, ist find
Befehl; Ein guter Weg, um zu überprüfen, ob sich etwas geändert hat, ist die mtime
einer Datei.
Die folgende Funktion gibt Ihnen einen Wert für die letzte Änderung (mtime) einer beliebigen Datei im angegebenen Verzeichnis
folder1="/path-to-folder"
find "${folder1}" -exec stat -c "%Y" \{\} \; \
| sort -n | tail -1
Ihr Skript könnte also folgendermaßen aussehen:
#!/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..."
AKTUALISIEREN
ein noch besserer ansatz wäre, den empfänger aktiv zu benachrichtigen, dass eine bestimmte datei übertragen wurde.
eine sehr einfache lösung wäre, nach der übertragung der payload auch eine leere Dummy-Datei zu kopieren. z.B. für eine Datei namens foo.avi
Kopieren Sie eine weitere Datei foo.avi.copyfinished
; Sie müssen also nur die Existenz von foo.avi.copyfinished
überprüfen um diese foo.avi
zu sehen ist fertig.
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
Diese Lösung erfordert offensichtlich die Zusammenarbeit von der sendenden Seite.
Verwandte:arduino – Programmierung mehrerer ICs mit einem einzigen USBasp/SPI-Bus und Arduino IDE?