BASH expressions arithmétiques

j'avais utilisé plusieurs façons de faire de l'arithmétique entière simple dans BASH (3.2). Mais je n'arrive pas à trouver la meilleure façon (préférée) de le faire.

result=`expr 1 + 2`
result=$(( 1 + 2 ))
let "result = 1 + 2"

Quelles sont les différences fondamentales entre ces expressions?

Est-il d'autres moyens de faire de même?

Est l'utilisation d'un outil comme bc obligatoire pour l'arithmétique à virgule flottante?

result=`echo "7/354" | bc`
18
demandé sur Arko 2010-03-25 20:07:50

5 réponses

Bash let permet des assignations multiples sur une ligne:

let a=3 b=4 c=5

comme vous le montrez dans votre question, citant l'argument à let vous permet de mettre des espaces autour des opérateurs. Vous pouvez, cependant, omettre les guillemets si vous évitez d'utiliser des espaces.

une autre forme utilisant des doubles parenthèses au début de la déclaration (au lieu de i=$((j + 1)) formulaire) vous permet d'inclure des espaces autour du signe égal ou post - ou pré - incrémentation ou de décrémentation et supplémentaires opérations d'affectation:

(( a = ( b + c ) * 4 ))
(( count++ ))
(( d = --c**2 ))
(( e *= 2 ))
(( f = 3, g = 5 ))    # multiple operations require a comma separator

Si vous n' help "((" il est dit que les doubles parenthèses est Équivalent à "let EXPRESSION".'

Vous pouvez utiliser le declare construire pour faire des assignations, y compris indirectement:

blue=2
name=blue
declare $name=4
echo $blue    # result: 4
echo ${!name} # result: 4

Edit:

$(()) la construction s'appelle" expansion arithmétique " et fait que le contenu soit évalué comme une expression entière. C'est un élément de syntaxe du Shell.

si une variable est déclarée comme un entier, vous n'avez pas besoin d'utiliser l'une ou l'autre des formes des doubles parenthèses, vous pouvez omettre le signe dollar du nom de la variable (comme dans les formes des doubles parenthèses), mais vous ne pouvez pas ajouter d'espaces autour des opérateurs:

declare -i x=1   # set integer, initialize to 1
declare +i s=1   # clear integer, initialize to 1
x+=1             # could also be x=x+1
echo $x          # result: 2 (addition)
s+=1             # could also be s=$s+1, requires a "$"
echo $s          # result: 11 (string concatenation)

Contrairement aux formulaires ci-dessus, appelant expr implique de fraie un exécutable externe qui peut être très coûteux pour beaucoup de calculs dans une boucle. l'heure à laquelle il faut l'utiliser est environnements dans lesquels le shell ne peut pas faire sa propre arithmétique ou pour la portabilité quand un script peut trouver son chemin dans un tel environnement. Les coques POSIX ont une capacité arithmétique de sorte qu'il serait une préoccupation seulement avec les systèmes plus anciens.

Concernant l'utilisation de bc pour l'arithmétique à virgule flottante, il ou quelque chose de similaire est nécessaire lors de L'utilisation de Bash et beaucoup d'autres coquilles. POSIX dit que " seulement signé long arithmétique entière est nécessaire."

deux coquilles supportant un flotteur les maths sont ksh et zsh. Outre bc, vous pouvez utiliser dc, AWK, Perl et d'autres de l'intérieur d'un script Bash.

Une chose que Bash faire avec des nombres à virgule flottante est de les imprimer avec le printf builtin (notez qu'il y a aussi un printf, mais les builtins ont la priorité).

printf "%'14.4f\n" 1234.56  # result "    1,234.5600" (in my locale)
17
répondu Dennis Williamson 2010-03-26 07:02:30

je préfère ta deuxième option, car elle n'a pas besoin d'un utilitaire externe:

result=$(( 1 + 2 ))

la première option appelle expr pour les mathématiques, je ne suis pas familier avec let. Une autre alternative à l' bcdc. Choisissez votre préféré.

5
répondu Carl Norum 2010-03-25 17:12:35

je ne peux pas dire que c'est "obligatoire" mais bc est probablement votre meilleur pari pour l'arithmétique générale.

pour quelque chose de plus fantaisiste, vous pouvez toujours passer par Perl.

$(()) appelle un processus enfant.

4
répondu DVK 2010-03-26 03:55:30

Is the use of a tool like bc mandatory for floating point arithmetic?

non, si vous utilisez un shell qui supporte la virgule flottante, par exemple zsh, ksh. Sinon, si vous voulez faire des maths plus avancées de point flottant, utilisez l'un de ceux-ci, bc/awk/dc. Bien sûr, Perl/Python etc ainsi.

3
répondu ghostdog74 2010-03-26 00:56:41

La troisième option que vous avez est beaucoup moins lisible qu'il ne ressemble pas à un opérateur d'affectation. Le premier, comme noté par d'autres, appelle une commande externe

0
répondu Aye 2010-03-25 17:16:01