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?