[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo $foo
[me@linuxbox ~]$ if (( foo = 5 ));then echo "It is true."; fi
It is true.
[me@linuxbox ~]$ echo $foo
5
En el ejemplo anterior, primero asignamos un valor vacío a la variable foo y verificamos que está realmente vacía. A continuación, realizamos un if con el comando compuesto (( foo = 5 )). Este proceso hace dos cosas interesantes: 1) asigna el valor 5 a la variable foo, y 2) se evalúa como verdadera porque se le asignó a foo un valor distinto de cero.
Nota: Es importante recordar el significado exacto del = en la expresión anterior. Un = individual realiza asignación. foo = 5 dice "haz a foo igual a 5", mientras == evalúa equivalencia. foo == 5 dice "¿es foo igual a 5? Esto puede ser muy confuso porque el comando test acepta un = individual para equivalencia de cadenas. Esta es otra razón más para usar los comandos compuestos más modernos [[ ]] y (( )) en lugar de test.
Además del =, el shell también ofrece notaciones que realizan algunas asignaciones muy útiles:
Tabla 34-4: Operadores de asignación
Notación | Descripción |
parámetro = valor | Asignación simple. Asigna valor a parámetro. |
parámetro += valor | Adición. Equivale a parámetro = parámetro + valor. |
parámetro -= valor | Sustracción. Equivale a parámetro = parámetro - valor. |
parámetro *= valor | Multiplicación. Equivale a parámetro = parámetro * valor. |
parámetro /= valor | División entera. Equivale a parámetro = parámetro / valor. |
parámetro %= valor | Módulo. Equivale a parámetro = parámetro % valor. |
parámetro ++ | Variable post-incremental. Equivale a parámetro = parámetro +1 (de todas formas, lo veremos continuación). |
parámetro -- | Variable post-decremental. Equivale a parámetro = parámetro - 1. |
++parámetro | Variable pre-incremental. Equivale a parámetro = parámetro +1. |
--parámetro | Variable pre-decremental. Equivale a parámetro = parámetro -1. |
Los operadores pueden aparecer delante o detrás de un parámetro. Aunque ambos aumentan o disminuyen el parámetro en uno, las dos localizaciones tienen una diferencia sutil. Si se coloca delante del parámetro , el parámetro aumenta (o disminuye) antes de que se devuelva el parámetro. Si se coloca después, la operación se realiza después de que el parámetro se devuelva. Esto es un poco extraño, pero está hecho a propósito. Aquí tenemos una demostración:
[me@linuxbox ~]$ foo=1
[me@linuxbox ~]$ echo $((foo++))
1
[me@linuxbox ~]$ echo $foo
2
Si asignamos el valor de uno a la variable foo y luego la incrementamos con el operador ++ situado tras el nombre del parámetro, foo es devuelto con el valor de uno. Sin embargo, si comprobamos el valor de la variable una segunda vez, vemos el valor incrementado. Si colocamos el operador ++ delante del parámetro, tenemos el comportamiento esperado:
[me@linuxbox ~]$ foo=1
[me@linuxbox ~]$ echo $((++foo))
2
[me@linuxbox ~]$ echo $foo
2
Para la mayoría de las aplicaciones de shell, colocar un prefijo al operador será lo más útil.
Los operadores ++ y -- se usan a menudo junto con los bucles. Haremos algunas mejoras en nuestro módulo de script ajustándolo un poco:
#!/bin/bash
# modulo2 : demonstrate the modulo operator
for ((i = 0; i <= 20; ++i )); do
if (((i % 5) == 0 )); then
printf "<%d> " $i
else
printf "%d " $i
fi
done
printf "\n"