2010-09-12 92 views

Répondre

1

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.

2

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 
+0

+1 n'a jamais connu la syntaxe de l'accolade – Kelvin