Je veux représenter plusieurs conditions comme celle-ci:
if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]
then
echo abc;
else
echo efg;
fi
mais quand j'exécute le script, ça montre
syntax error at line 15: `[' unexpected,
où la ligne 15 est celle indiquant si ....
Quel est le problème avec cette condition? Je suppose que quelque chose ne va pas avec le ()
.
test
([
) et non par le shell. Le shell évalue uniquement l'état de sortie de[
.Réponses:
Technique classique (métacaractères d'échappement):
J'ai joint les références à
$g
entre guillemets; c'est une bonne pratique, en général. Strictement, les parenthèses ne sont pas nécessaires car la priorité de-a
et la-o
rend correcte même sans elles.Notez que les opérateurs
-a
et-o
font partie de la spécification POSIX pourtest
, alias[
, principalement pour la compatibilité descendante (car ils faisaient partie de latest
7e édition UNIX, par exemple), mais ils sont explicitement marqués comme `` obsolètes '' par POSIX. Bash (voir les expressions conditionnelles ) semble préempter les significations classiques et POSIX pour-a
et-o
avec ses propres opérateurs alternatifs qui prennent des arguments.Avec un peu de soin, vous pouvez utiliser l'
[[
opérateur le plus moderne , mais sachez que les versions dans Bash et Korn Shell (par exemple) n'ont pas besoin d'être identiques.Exemple d'exécution, en utilisant Bash 3.2.57 sur Mac OS X:
Vous n'avez pas besoin de citer les variables
[[
comme vous le faites[
car ce n'est pas une commande distincte de la même manière[
.Je l'aurais pensé. Cependant, il existe une autre alternative, à savoir:
En effet, si vous lisez les directives du «shell portable» pour l'
autoconf
outil ou les packages associés, cette notation - en utilisant «||
» et «&&
» - est ce qu'ils recommandent. Je suppose que vous pourriez même aller jusqu'à:Lorsque les actions sont aussi triviales que l'écho, ce n'est pas mauvais. Lorsque le bloc d'action à répéter est composé de plusieurs lignes, la répétition est trop douloureuse et l'une des versions antérieures est préférable - ou vous devez encapsuler les actions dans une fonction qui est invoquée dans les différents
then
blocs.la source
-a
en fait une priorité plus élevée que-o
(contrairement à&&
et||
dans le shell - cependant, à l' intérieur desbash
[[ ... ]]
conditionnelles , a&&
également une priorité plus élevée que||
). Si vous vouliez éviter-a
et-o
pour une robustesse et une portabilité maximales - ce que la page de manuel POSIX suggère elle-même - vous pouvez également utiliser des sousif ([ $g -eq 1 ] && [ "$c" = "123" ]) || ([ $g -eq 2 ] && [ "$c" = "456" ])
if test "$g" -eq 1 -a "$c" = "123" || test "$g" -eq 2 -a "$c" = "456"; then ...
&&
ou||
est également préférable car elle se comporte plus comme des conditions dans d'autres langues et vous permet de court-circuiter les conditions. Par exemple:if [ -n "${check_inodes}" ] && [ "$(stat -f %i "/foo/bar")" = "$(stat -f %i "/foo/baz")" ]
. En procédant de cette façon, sicheck_inodes
est vide, vous évitez deux appels àstat
, tandis qu'une condition de test plus grande et complexe doit traiter tous les arguments avant de s'exécuter (ce qui peut également entraîner des bogues si vous oubliez ce comportement).Dans Bash:
la source
bash
. En aparté: dans ce cas particulier, les parenthèses ne sont même pas nécessaires, car l' intérieur des[[ ... ]]
conditions a&&
en fait une priorité plus élevée que||
- contrairement à l' extérieur de telles conditions.if
/else
et avoir le code entrethen
etfi
mettre une fonction afin d'éviter de la répéter. Dans des cas très simples, vous pouvez utiliser unecase
instruction avec;&
fallthrough (dans Bash 4).L'utilisation de
/bin/bash
ce qui suit fonctionnera:la source
Soyez prudent si vous avez des espaces dans vos variables de chaîne et que vous vérifiez leur existence. Assurez-vous de les citer correctement.
la source
la source
{ ;}
pourrait être utilisé à la place.En bash pour la comparaison de chaînes, vous pouvez utiliser la technique suivante.
Exemple:
la source
la source
vous pouvez également chaîner plus de 2 conditions:
la source