ET logique dans un script bash

10

J'ai un ifdans mon script bash qui doit vérifier si l'un des 2 fichiers existe, s'ils n'existent pas, il devrait correspondre à l'écho.

Code que j'ai:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Mais cela ne semble pas fonctionner pour une raison quelconque.

Je suis sûr à 110% que ces 2 fichiers n'existent pas. Je ne reçois aucune erreur, il n'entre simplement pas dans le if.

Je suis nouveau dans les scripts bash, donc je ne suis pas sûr de ce qui pourrait mal se passer.

Peppercat101
la source
Je ne pense pas que les réponses publiées répondent à la question. Que se passe-t-il lorsque vous essayez les tests individuellement? Faites [[ ! -f /etc/.../... ]]; echo $?pour chacun.
jw013
Un avertissement : [[ -f xxx ]]renvoie vrai si xxx existe et est un fichier normal (ou un lien symbolique vers un fichier normal). Il retournera false s'il n'existe pas, ou s'il ne peut pas dire s'il existe ou non ou s'il existe mais n'est pas un fichier normal (répertoire, pipe, périphérique, socket ...) ou s'il s'agit d'un lien symbolique à un fichier qui n'existe pas ou qui ne peut pas dire s'il existe ou non ou n'est pas un fichier normal ... [[ -e $file ]] || [[ -L $file ]]est plus proche d'un test d'existence. ls -d -- "$file" > /dev/null 2>&1est encore plus proche. Et en règle générale, ce type de test conduit à des conditions de course. Peut-être qu'il y a une autre façon.
Stéphane Chazelas

Réponses:

12

Si vous voulez soit vous voulez OR, non AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Cela correspondra si l'un ou les deux fichiers sont manquants.
  • Votre code ne s'imprimera que matchsi les deux n'existent pas.

Mais vous avez dit:

Je suis sûr à 110% que ces 2 fichiers n'existent pas. Je ne reçois aucune erreur, il n'entre simplement pas le if.

Votre déclaration se contredit donc. Au moins un de ces fichiers doit exister si vous exécutez ce code.

Si vous souhaitez voir comment votre ifinstruction est en cours d'évaluation, exécutez-la avec -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Ensuite, vous verrez l'exécution.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 
bahamat
la source
Je veux qu'il fasse écho "match" si aucun fichier n'existe, s'il existe, il ne correspond pas à l'impression. Je vais l'essayer avec -x
Peppercat101
Dans ce cas, votre code d'origine devrait convenir. Et en effet, cela fonctionne pour moi.
bahamat
3

Cela ne devrait-il pas être ainsi? A est un fichier ou B est un fichier, puis blabla.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi
Marguerite
la source
3

Cela peut également fonctionner pour ce que vous essayez de faire. Les parenthèses simples ne sont pas couramment utilisées aujourd'hui avec bash, mais c'est toujours une option. L'utilisation de '-o' est en fait une opération "OU" et "!" nie la condition.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"
slashdot
la source
Ne jamais utiliser [dans bash. Mis à part cela, je ne vois pas comment cela répond à la question.
jw013
[ ! -f ${var} -a ! -f {var}.class ] && echo "match"ça devrait être. La quête était: s'ils (les deux) n'existent pas, cela devrait echo match.
hschou
0

Votre code répond à vos besoins: il s'imprimera à matchcondition qu'il ne trouve aucun fichier.

Par conséquent, la raison matchn'est pas imprimée ailleurs. Vous devez confirmer que le bloc de code est atteint, ce que vous pouvez faire en l'entourant de quelques messages de débogage. Par exemple, comme ceci:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

Ma préférence habituelle est que les messages de débogage soient envoyés à stderr afin d'éviter d'interrompre le flux de données vers stdout , mais je l'ai évité ici parce que vous avez dit que vous étiez un débutant. Voici un exemple montrant comment vous pourriez écrire sur stdout :

echo '@ About to enter if...fi block' >&2
roaima
la source