J'ai le script suivant qui vérifie s'il y a un fichier dans un dossier et si le fichier est stable (c'est pour les gros fichiers vidéo que je reçois).
#!/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
Comment modifier le script pour qu'il puisse vérifier plusieurs fichiers dans le même dossier et après qu'ils soient tous stables pour démarrer le script de conversion ?
Réponse acceptée :
il y a un certain nombre de problèmes dans votre script, à commencer par :
folder1="path-to-folder"
cd $folder1
while file=$(ls "$folder1") ...
cela fait vraiment cd path-to-folder; ls path-to-folder
; si path-to-folder
est absolu (commençant par un '/' comme dans votre exemple) cela peut fonctionner, mais cela ne fonctionnera pas chaque fois que vous utilisez des chemins relatifs.
cela ne fonctionnera pas non plus si path-to-folder
contient des espaces, car vous devez utiliser des guillemets partout, par ex. cd "$folder1"
puis en faisant un while file=$(ls ...)
fera une boucle infinie, comme file
sera toujours défini sur quelque chose (le contenu du répertoire).
la syntaxe appropriée serait for file in $(ls ...)
, qui cessera de fonctionner dès que vous aurez des noms de fichiers avec des espaces (car la boucle s'exécutera sur foo
et bar
si vous avez un fichier nommé foo bar
). vérifiez pourquoi vous ne devriez jamais analyser la sortie de ls. au lieu d'utiliser ls
vous pouvez simplement faire for file in *
.
enfin, vous pourriez avoir des fichiers qui changent même si leur taille ne change plus.
un bon moyen d'itérer sur les fichiers est le find
commande; un bon moyen de vérifier si quelque chose a changé est le mtime
d'un fichier.
la fonction suivante vous donne une valeur pour la dernière modification (mtime) de n'importe quel fichier dans le répertoire donné
folder1="/path-to-folder"
find "${folder1}" -exec stat -c "%Y" \{\} \; \
| sort -n | tail -1
donc votre script pourrait ressembler à :
#!/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..."
MISE À JOUR
une approche encore meilleure serait de notifier activement le récepteur qu'un fichier donné a été transmis.
une solution très simple serait de copier également un fichier factice vide après la transmission de la charge utile. par exemple. pour un fichier nommé foo.avi
copier un autre fichier foo.avi.copyfinished
; il vous suffit donc de vérifier l'existence de foo.avi.copyfinished
pour voir que foo.avi
est prêt.
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
cette solution nécessite évidemment la coopération du côté expéditeur.
Connexe :arduino – Programmation de plusieurs circuits intégrés à l'aide d'un seul bus USBasp/SPI et d'un IDE Arduino ?