Comme d'autres l'ont expliqué, l'utilisation inotify
est la meilleure solution. Je vais juste expliquer pourquoi votre script échoue. Tout d'abord, quel que soit le langage dans lequel vous programmez, chaque fois que vous essayez de déboguer quelque chose, la première règle est "imprimer toutes les variables":
$ ls
file1 file2 file3
$ echo $PWD
/home/terdon/foo
$ for FILE in "${PWD}/*"; do echo "$FILE"; done
/home/terdon/foo/*
Ainsi, comme vous pouvez le voir ci-dessus, $FILE
est en fait étendu à $PWD/*
. Par conséquent, la boucle n'est exécutée qu'une seule fois sur la chaîne /home/terdon/foo/*
et non sur chacun des fichiers du répertoire individuellement. Ensuite, la md5sum
commande devient:
md5sum /home/terdon/foo/*
En d'autres termes, il s'exécute simultanément md5sum
sur tous les fichiers du répertoire cible et non sur chacun d'eux.
Le problème est que vous citez votre expansion globale et cela l'empêche d'être développée:
$ echo "*"
*
$ echo *
file1 file2 file3
Alors que les variables doivent presque toujours être citées , les globes ne devraient pas, car cela les transforme en chaînes au lieu de globes.
Ce que vous vouliez faire, c'est:
for FILE in "${PWD}"/*; do ...
Cependant, il n'y a aucune raison de l'utiliser $PWD
ici, cela n'ajoute rien d'utile. La ligne ci-dessus équivaut à:
for FILE in *; do
Évitez également d'utiliser des lettres CAPITAL pour les variables shell. Ceux-ci sont utilisés pour les variables d'environnement définies par le système et il est préférable de conserver vos propres variables en minuscules.
Avec tout cela à l'esprit, voici une version améliorée et fonctionnelle de votre script:
#!/bin/bash
for file in *
do
sum1="$(md5sum "$file")"
sleep 2
sum2="$(md5sum "$file")"
if [ "$sum1" = "$sum2" ];
then
echo "Identical"
else
echo "Different"
fi
done
for FILE in "${PWD}"/*; do
fonctionne sur le même ensemble,for FILE in *; do
il n'est pas exactement équivalent car ce dernier n'inclut pas les chemins d'accès.md5sum -- "$file"
au lieu demd5sum "$file"
gérer le cas où un fichier commence par un-
. Bien sûr, vous devez également faire en sorte que votre implémentation de md5sum prenne en charge le--
délimiteur de fin d'options.Vous pouvez certainement utiliser inotify-tools à partir de la ligne de commande, par exemple comme ceci:
De l' homme inotifywait
Et voici un script qui surveille en continu, copié du fichier man de
inotifywait
:la source
Vous pouvez utiliser le
inotify-tools
package pour surveiller toutes les modifications dans un dossier en temps réel. Par exemple, il contient l'inotifywait
outil que vous pouvez utiliser comme:Vous pouvez utiliser des indicateurs pour filtrer certains événements uniquement ou certains fichiers. L'
inotifywatch
outil collecte les statistiques d'utilisation du système de fichiers et génère le nombre de chaqueinotify
événement.Vous pouvez trouver plus d'exemples ici par exemple.
Si vous souhaitez surveiller avec d'autres outils, vous pouvez utiliser
find
avec le-mmin
paramètre (minutes modifiées). Puisque 2 secondes est comme 0,033 minutes, vous pouvez utiliser:la source
Si vous souhaitez surveiller sur un intervalle de deux secondes, vous pouvez entourer votre chèque avec:
Bien que cela teste séquentiellement les fichiers et attende 2 secondes pour chaque fichier trouvé, je suggère de transformer votre chèque en fonction:
Qui peut être utilisé dans la
while
boucle:Veuillez noter l'
&
esperluette pour effectuer les vérifications en arrière-plan pour effectuer les vérifications de fichiers en parallèle. Notez que cela peut avoir un impact sur les performances en fonction du nombre de fichiers trouvés dans le répertoire.Notez également que j'ai modifié les
echo
lignes pour inclure le nom de fichier ("$@"
) afin de visualiser le fichier trouvé identique / différent.la source
la source