web-dev-qa-db-fra.com

Bash: utilisation du résultat d'un diff dans une instruction if

J'écris un simple script Bash pour détecter quand un dossier a été modifié.

C'est quelque chose de très proche de:

ls -lR $dir > a
ls -lR $dir > b

DIFF=$(diff a b) 
if [ $DIFF -ne 0 ] 
then
    echo "The directory was modified"

Malheureusement, l'instruction if affiche une erreur: [: -ne: opérateur unaire attendu

Je ne sais pas ce qui ne va pas avec mon script, est-ce que quelqu'un pourrait m'aider?

Merci beaucoup!

Jary

50
Jary
ls -lR $dir > a
ls -lR $dir > b

DIFF=$(diff a b) 
if [ "$DIFF" != "" ] 
then
    echo "The directory was modified"
fi
45
Lou Franco
if ! diff -q a b &>/dev/null; then
  >&2 echo "different"
fi
49
Paul Tomblin

Vous recherchez la valeur de retour de diff et non la sortie de diff que vous utilisez dans votre exemple de code.

Essaye ça:

diff a b
if [ $? -ne 0 ]; then
    echo "The directory was modified";
fi
25
tangens
DIFF=$(diff -u <(find dir1/ -type f -printf '%P\n' | sort) <(find dir2/ -type f -printf '%P\n' | sort))
if [ "$DIFF" ]; then
  echo "Directories differ"
  # Do other stuff here
fi

Celui-ci utilise l'un de mes bashismes préférés, la substitution de processus <().

La variable $DIFF Contient une différence imprimable. Si vous souhaitez le montrer à l'utilisateur final, assurez-vous de le mettre entre guillemets, par ex. echo "$DIFF".

Si vous voulez seulement dire à l'utilisateur qu'il y a eu une différence , si elle peut être raccourcie en quelque chose comme [ "$(diff ...)" ] && echo "Difference found"

Remarque: Je suppose que la question d'origine était censée avoir dir1 Et dir2 Pour donner un peu plus de sens. Si c'était dir au temps 0 puis dir au temps 1, cette approche ne fonctionnerait évidemment pas.

1
Aaron D. Marasco

Si vous n'avez pas besoin de connaître les modifications, cmp suffit. De plus, vous pouvez jouer avec l'astuce syntaxique fournie par et ||:

cmp a b || echo 'The directory was modified'

L'instruction peut être interprétée comme: "soit a et b sont égaux, soit je fais écho au message".

(La sémantique de && et || doit être manipulé avec soin, mais ici c'est intuitif).

Juste pour des raisons de lisibilité, je préfère en fait le mettre sur deux lignes:

cmp a b \
  || echo 'The directory was modified'
0