He intentado incrementar una variable numérica usando ambos var=$var+1
y var=($var+1)
sin éxito. La variable es un número, aunque bash parece leerla como una cadena.
Bash versión 4.2.45 (1)-lanzamiento (x86_64-pc-linux-gnu) en Ubuntu 13.10.
He intentado incrementar una variable numérica usando ambos var=$var+1
y var=($var+1)
sin éxito. La variable es un número, aunque bash parece leerla como una cadena.
Bash versión 4.2.45 (1)-lanzamiento (x86_64-pc-linux-gnu) en Ubuntu 13.10.
Hay más de una forma de incrementar una variable en bash, pero lo que intentaste no es correcto.
Puedes usar por ejemplo expansión aritmética:
var=$((var+1))((var=var+1))((var+=1))((var++))
O puedes usar let
:
let "var=var+1"let "var+=1"let "var++"
Véase también: http://tldp.org/LDP/abs/html/dblparens.html.
var=$((var + 1))
Usos de la aritmética en bash $((...))
sintaxis.
Gracias a Respuesta de Radu Rădeanu eso proporciona las siguientes formas de incrementar una variable en bash:
var=$((var+1))((var=var+1))((var+=1))((var++))let "var=var+1"let "var+=1" let "var++"
También hay otras formas. Por ejemplo, mire las otras respuestas a esta pregunta.
let var++var=$((var++))((++var)){ declare -i var var=var+1 var+=1}{ i=0 i=$(expr $i + 1)}
Tener tantas opciones lleva a estas dos preguntas:
#!/bin/bash# To focus exclusively on the performance of each type of increment# statement, we should exclude bash performing while loops from the# performance measure. So, let's time individual scripts that# increment $i in their own unique way.# Declare i as an integer for tests 12 and 13.echo > t12 'declare -i i; i=i+1'echo > t13 'declare -i i; i+=1'# Set i for test 14.echo > t14 'i=0; i=$(expr $i + 1)'x=100000while ((x--)); do echo >> t0 'i=$((i+1))' echo >> t1 'i=$((i++))' echo >> t2 '((i=i+1))' echo >> t3 '((i+=1))' echo >> t4 '((i++))' echo >> t5 '((++i))' echo >> t6 'let "i=i+1"' echo >> t7 'let "i+=1"' echo >> t8 'let "i++"' echo >> t9 'let i=i+1' echo >> t10 'let i+=1' echo >> t11 'let i++' echo >> t12 'i=i+1' echo >> t13 'i+=1' echo >> t14 'i=$(expr $i + 1)'donefor script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; do line1="$(head -1 "$script")" printf "%-24s" "$line1" { time bash "$script"; } |& grep user # Since stderr is being piped to grep above, this will confirm # there are no errors from running the command: eval "$line1" rm "$script"done
i=$((i+1)) user 0m0.992si=$((i++)) user 0m0.964s((i=i+1)) user 0m0.760s((i+=1)) user 0m0.700s((i++)) user 0m0.644s((++i)) user 0m0.556slet "i=i+1" user 0m1.116slet "i+=1" user 0m1.100slet "i++" user 0m1.008slet i=i+1 user 0m0.952slet i+=1 user 0m1.040slet i++ user 0m0.820sdeclare -i i; i=i+1 user 0m0.528sdeclare -i i; i+=1 user 0m0.492si=0; i=$(expr $i + 1) user 0m5.464s
Parece que Bash es el más rápido en el rendimiento i+=1
cuando $i
se declara como un entero. let
las declaraciones parecen particularmente lentas, y expr
es, con mucho, el más lento porque no está integrado en bash.
También está esto:
var=`expr $var + 1`
Tome nota cuidadosa de los espacios y también ` no es '
Si bien las respuestas de Radu y los comentarios son exhaustivos y muy útiles, son específicos de bash. Sé que preguntaste específicamente sobre bash, pero pensé en participar ya que encontré esta pregunta cuando estaba buscando hacer lo mismo usando sh en busybox en uClinux. Esto va más allá de bash.
Si declaras $var
como un entero, entonces lo que probaste la primera vez realmente funcionará:
$ declare -i var=5$ echo $var5$ var=$var+1$ echo $var6
Referencia: Tipos de variables, Guía de Bash para Principiantes
Hay un método que falta en todas las respuestas - bc
$ VAR=7 $ bc <<< "$VAR+2"9$ echo $VAR7$ VAR=$( bc <<< "$VAR+1" )$ echo $VAR8
bc
se especifica por POSIX estándar, por lo que debería estar presente en todas las versiones de Ubuntu y sistemas compatibles con POSIX. El <<<
la redirección podría modificarse para echo "$VAR" | bc
para la portabilidad, pero dado que la pregunta se refiere a bash
- está bien usar <<<
.
El código de retorno 1
el problema está presente para todas las variantes predeterminadas (let
, (())
, sucesivamente.). Esto a menudo causa problemas, por ejemplo, en scripts que usan set -o errexit
. Esto es lo que estoy usando para evitar el código de error 1
de expresiones matemáticas que evalúan a 0
;
math() { (( "$@" )) || true; }math a = 10, b = 10math a++, b+=2math c = a + bmath mod = c % 20echo $a $b $c $mod#11 12 23 3
Esta tiene que ser la peor manera de lograr una tarea tan simple, pero supongo que solo quería documentarla por diversión (todo lo contrario de code golf).
$ var=0$ echo $var0$ var="$(python -c 'print('$var'+1)')"$ echo $var1
o
$ var="$(printf '%s\n' $var'+1' | bc)"$ echo $var1
En serio, utilice una de las otras opciones mucho mejores aquí.
Esta es la apuesta segura
(( var = var + 1 ))
Si el valor resultante no es cero, establecer exit en error detendrá el script
set -evar=0(( var++ ))echo You will never get here