expr
ne semble pas aimer les parenthèses (utilisées en mathématiques selon la priorité explicite de l'opérateur):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Comment exprimer la priorité de l'opérateur dans bash?
shell
quoting
arithmetic
expr
Nicolas Raoul
la source
la source
let
. Ce n'est pas plus standard ou portable que(( a = 3 * (2 + 1) ))
(les deux viennent deksh
et ne sont disponibles qu'en ksh, bash et zsh) et il est moins lisible ou facile à citer. Utiliseza=$((3 * (2 + 1)))
pour être portable.((a = 3 * (2 + 1) ))
, une pour la portabilitéa=$((3 * (2 + 1)))
), donc ce n'est pas une note contre vous ou votre réponse mais contre le fait qu'elle soit la réponse choisie et meilleur buteur.a=1 $[a+2]
oua=1 b=2 $[a+b]
. Est-ce leur raison d'éviter cette syntaxe?Vous pouvez utiliser plutôt l’expansion arithmétique.
À mon avis, cela semble un peu plus agréable que d’utiliser
expr
.De
man bash
la source
Il n'y a aucune raison d'utiliser l'
expr
arithmétique dans les coques modernes.POSIX définit l'
$((...))
opérateur d'extension. Vous pouvez donc utiliser cela dans tous les shells compatibles POSIX (lessh
plus modernes, comme dash, dash, bash, yash, mksh, zsh, posh, ksh ...).ksh
a également introduit une commandelet
intégrée qui est transmise au même type d'expression arithmétique, ne se développe pas en quelque chose, mais retourne un statut de sortie basé sur le fait que l'expression soit résolue ou non, comme dansexpr
:Cependant, comme les citations le rendent maladroit et pas très lisible (pas dans la même mesure que
expr
bien sûr),ksh
introduit également une((...))
forme alternative:ce qui est beaucoup plus lisible et devrait être utilisé à la place.
let
et((...))
ne sont disponibles que dansksh
,zsh
etbash
. La$((...))
syntaxe doit être privilégiée si la portabilité vers d'autres shells est nécessaire, si elleexpr
est utilisée uniquement pour les shells pré-POSIX de type Bourne (généralement le shell Bourne ou les premières versions du shell Almquist).Sur le front non Bourne, il y a quelques obus avec un opérateur arithmétique intégré:
csh
/tcsh
(réellement le premier shell Unix avec évaluation arithmétique intégrée):akanga
(basé surrc
)Comme note historique, la version originale du shell Almquist, telle que publiée sur usenet en 1989, comportait une fonction
expr
intégrée (fusionnée avectest
), mais elle a été supprimée ultérieurement.la source
: $((a = a*2))
vous$((...))
comme zsh, ksh93 ou yash.expr
est une commande externe, ce n’est pas une syntaxe de shell spéciale. Par conséquent, si vous souhaitezexpr
voir les caractères spéciaux du shell, vous devez les protéger de l'analyse syntaxique du shell en les citant. De plus,expr
chaque numéro et chaque opérateur doivent être passés en tant que paramètre séparé. Ainsi:Sauf si vous travaillez sur un système Unix antique des années 1970 ou 1980, il y a très peu de raisons de l'utiliser
expr
. Auparavant, les coquilles n'avaient pas de méthode intégrée pour effectuer des calculs, et vous deviez appeler l'expr
utilitaire à la place. Tous les shells POSIX ont l'arithmétique intégrée via la syntaxe d' expansion arithmétique .La construction se
$((…))
développe jusqu'au résultat de l'expression arithmétique (écrite en décimal). Bash, comme la plupart des shells, ne supporte que l'arithmétique entière modulo 2 64 (ou modulo 2 32 pour les anciennes versions de bash et d'autres shells sur les machines 32 bits).Bash offre une syntaxe de commodité supplémentaire lorsque vous souhaitez effectuer des tâches ou pour tester si une expression est 0 mais ne vous souciez pas du résultat. Cette construction existe également dans ksh et zsh mais pas dans plain sh.
En plus de l'arithmétique entière,
expr
offre quelques fonctions de manipulation de chaîne. Celles-ci aussi sont assimilées aux fonctionnalités des shells POSIX, à l'exception de l'une des suivantes:expr STRING : REGEXP
teste si la chaîne correspond à l'expression rationnelle spécifiée. Un shell POSIX ne peut pas le faire sans outils externes, mais bash avec[[ STRING =~ REGEXP ]]
(avec une syntaxe d'expression régulière différente -expr
est un outil classique et utilise BRE, bash utilise ERE).À moins que vous n'utilisiez des scripts exécutés sur des systèmes vieux de 20 ans, vous n'avez pas besoin de savoir que cela a
expr
déjà existé. Utilisez l'arithmétique des coques.la source
expr foo : '\(.\)'
fait aussi l'extraction de texte.bash
« sBASH_REMATCH
permette d' obtenir quelque chose de similaire. Il effectue également une comparaison des chaînes, ce que POSIX[
ne fait pas (bien que l'on puisse imaginer des façons d'utilisersort
cela).Utilisez des parenthèses avec des guillemets:
Les guillemets empêchent bash d’interpréter la parenthèse en tant que syntaxe bash.
la source
expr
ligne de commande doivent être séparés par des espaces. alors; par exemple,expr 3 "*" "(2" "+" "1)"
ne fonctionnera pas . (En outre, BTW, vous n'avez probablement pas besoin de citer le+
.)while
et[[
, ils sont la syntaxe. S'ils étaient des mots-clés, ils ne seraient pas interprétés comme tels dans les arguments de commande. Vous avez besoin de guillemets pour que bash ne les analyse pas mais affiche un littéral de chaîne.Si vous avez bc ..
la source