Essayez de comprendre comment convertir un argument en un entier sur lequel effectuer une arithmétique, puis l’imprimer, par exemple pour addOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Essayez de comprendre comment convertir un argument en un entier sur lequel effectuer une arithmétique, puis l’imprimer, par exemple pour addOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Réponses:
En bash, on ne "convertit pas un argument en entier pour effectuer une arithmétique". Dans bash, les variables sont traitées comme des entiers ou des chaînes selon le contexte.
Pour effectuer une opération arithmétique, vous devez appeler l'opérateur d'expansion arithmétique $((...))
. Par exemple:
$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3
ou généralement préféré:
$ echo "$((a + 1))"
3
Vous devez savoir que bash (contrairement à ksh93, zsh ou yash) exécute uniquement des calculs arithmétiques entiers . Si vous avez des nombres à virgule flottante (nombres avec décimales), il existe d'autres outils pour vous aider. Par exemple, utilisez bc
:
$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14
Ou vous pouvez utiliser un shell avec support arithmétique en virgule flottante au lieu de bash:
zsh> echo $((3.14 + 1))
4.14
Dans bash
, vous pouvez effectuer la conversion de n'importe quoi en entier à l’aide de printf -v :
printf -v int '%d\n' "$1" 2>/dev/null
Les nombres flottants seront convertis en nombres entiers, alors que tout ce qui ne ressemble pas à un nombre sera converti en 0. L'exponentiation sera tronquée au nombre précédent e
Exemple:
$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
printf -v
ceci peut être réalisé avec substitution de commande:int="$(printf '%d' 123.123 2>/dev/null)"
bash
vous utilisée?
Une situation similaire est apparue récemment lors du développement de scripts bash à exécuter dans les environnements Linux et OSX. Le résultat d’une commande sous OSX a renvoyé une chaîne contenant le code de résultat; c'est à dire " 0"
. Bien sûr, cela n'a pas réussi à tester correctement dans le cas suivant:
if [[ $targetCnt != 0 ]]; then...
La solution consistait à forcer (c'est-à-dire à "convertir") le résultat en un entier similaire à ce que @ John1024 avait répondu ci-dessus, de sorte qu'il fonctionne comme prévu
targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
==
etc dans [[
(également [
aka test
) faire la comparaison de chaîne. Il existe différents opérateurs pour la comparaison arithmétique, par exemple [[ $targetcnt -ne 0 ]]
; voir la page de manuel (ou info) sous Expressions conditionnelles. Pour découper des espaces spécifiquement, vous pouvez utiliser [
un développement de variable non entre [ $targetcnt == 0 ]
guillemets pour obtenir un déchiffrage de mots par défaut (NON effectué dans [[
), mais en général, cette approche vous met en danger.
attention aux codes de couleur, même dans trace ( -x
), ils n'apparaîtront pas. Ce qui serait révélé, c'est que la chaîne supposée être un nombre est entourée de guillemets, quelle que soit la manière dont vous l'imprimez.
$((var+var))
fail échouent mais si vous echo
ou les printf
deux vars ils sont les mêmes. Je ne connais pas le correctif, car je n'ai pu le résoudre qu'en désactivant les codes de couleur à la source de la sortie. Pour le repérer dans les journaux de suivi, vous verrez la variable incriminée affectée comme var='0'
il se doitvar=0
sed
si vous ne pouvez pas la désactiver
printf "1 + %s\n" $1 won't do ?