Je pensais que le script shell C se comporterait comme C et utiliserait l'évaluation de court-circuit pour les opérateurs logiques. Mais dans l'instruction if, même si la première condition est vraie, la seconde est vérifiée et me donne des erreurs. Avons-nous un court-circuit OU logique dans un script shell C?Avons-nous des opérateurs logiques de court-circuit dans le script shell C?
Répondre
Habituellement, &&
et ||
sont court-circut. Considérons quelque chose comme ceci:
$ false && echo foo
$ true || echo foo
Dans les deux cas, foo ne sera pas éteint. Mais, AFAIK vous ne pouvez pas utiliser ce genre de comparaison de chaînes comme ça, même si court-circuit, csh va encore vérifier la syntaxe dans son ensemble.
Oui, &&
et ||
sont des opérateurs de court-circuit dans tcsh (comme ils le sont en C). Et il existe deux formes distinctes, une qui fonctionne sur les commandes (comme dans false && echo foo
), et une qui fonctionne sur l'expression (comme dans if (-e $file1 && -e $file2)
).
Je ne suis pas entièrement sûr de ce qui se passe ici, sauf que csh et tcsh sont connus pour leur syntaxe mal définie. Un peu d'expérimentation montre que sauver la sortie de find
dans une variable permet d'éviter l'erreur: (. Notez que les parenthèses supplémentaires ne sont pas vraiment nécessaires, mais ils ne font pas mal quoi que ce soit)
set s = "`find $monitor -newer $cache`"
if ((! -e $cache) || ("$s" != "")) then
echo ok
endif
Mais plus d'amélioration est possible. Stocker la sortie entière de la commande find dans une variable n'est pas vraiment nécessaire. Au lieu de cela, vous pouvez appeler trouver et utiliser son statut de retour pour vous dire s'il a trouvé quoi que ce soit:
Je viens d'essayer ceci:
if (! -e $cache || { find $monitor -newer $cache >& /dev/null }) then
echo ok
endif
et cela a fonctionné - sauf que la redirection >& /dev/null
semble être ignoré dans les les accolades. Au lieu de cela, vous pouvez exécuter la commande "find" séparément, puis examiner l'état $ qui en résulte. Ce qui signifie que vous perdez le bénéfice de l'opérateur ||
de court-circuit; vous devrez utiliser des instructions if
imbriquées et/ou des variables temporaires. Peut-être que la vraie leçon est la suivante: j'utilise csh et tcsh depuis plus d'années que je ne veux l'admettre, et la seule façon de comprendre ce genre de choses était de faire des essais et des erreurs. Vous pouvez faire cela en utilisant tcsh ou csh, mais vous êtes probablement mieux d'utiliser un langage de script différent. Par exemple, dans Bourne shell, c'est assez simple:
if [ ! -e $cache ] || find $monitor -newer $cache >/dev/null 2>&1 ; then
...
fi
+1 n'a jamais connu la syntaxe de l'accolade – Kelvin