Bash no tiene el concepto de valores Boolean. Existen strings y números, y arrays de strings o números. Entonces, ¿cómo manejan los comandos condicionales lo verdadero y lo falso?
Los comandos producen un estado de salida cuando terminan. Un estado de salida es un número entero entre 0 y 255, ambos inclusive. Bash considera que un estado de salida cero representa éxito. Cualquier otro estado de salida representa fallo.
Esto aplica a todos los comandos, incluidos los comandos integrados de Bash, las palabras clave y las funciones.
La sintaxis básica del comando if es
if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi
Empieza con if; los comandos de condición se separan de los comandos de «éxito» con then; y termina con fi.
La cláusula else es opcional.
Los CONDITIONAL_COMMANDS pueden ser un solo comando o pueden ser una lista de comandos.
Se ejecutan los CONDITIONAL_COMMANDS y
Se pueden dar ramas en cascada con elif
if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi
Debe haber un punto y coma o un salto de línea antes de las palabras then, elif, else y fi.
Para enfatizar: es el estado de salida de los comandos condicionales lo que controla el flujo.
Por ejemplo, grep devuelve 0 si encuentra una coincidencia, y 1 si no la encuentra.
La opción -q suprime la salida y solo produce el estado de salida.
if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi
No hay una sintaxis especial alrededor de los CONDITIONAL_COMMANDS.
Es posible que hayas visto sentencias if como esta:
if [ "$password" = "secure" ]; then
echo "Welcome!"
fi
[ no es una sintaxis especial.
Es un comando que evalúa la expresión condicional y termina con un estado de éxito o de fallo.
Como todos los comandos, se requiere espacio en blanco entre él y sus argumentos.
En realidad, [ es un sinónimo del comando test.
Son exactamente lo mismo, excepto que el último argumento de [ debe ser ].
Dentro de [ y ], escribes una expresión condicional.
Algunas expresiones condicionales típicas son:
[ -f "$filename" ] # file operations
[ "$string1" = "$string2" ] # string comparisons
[ "$num1" -eq "$num2" ] # arithmetic comparisons
Hay muchas más operaciones disponibles; están en la sección Expresiones condicionales de Bash del manual.
En los ejemplos anteriores, fíjate que todas las variables están entre comillas.
Los comandos test y [ son comandos normales, donde los argumentos están sujetos a la división de palabras y a la expansión de nombres de archivo como cualquier otro comando.
Vale la pena señalarlo porque las expresiones condicionales se evalúan de forma distinta según cuántos argumentos proporciones:
[ -z "$name" ]), o un ! (que niega el estado de la prueba de 1 argumento)Puedes obtener resultados inesperados si olvidas poner las comillas:
str=""
# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi
# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi
El constructor condicional [[...]] no es un comando, es una palabra clave.
Esto significa que, aunque se maneja como cualquier otro comando, tiene reglas de análisis sintáctico especiales.
Lo especial de [[ es que las variables que se expanden dentro de él no están sujetas a la división de palabras ni a la expansión de nombres de archivo.
Eso significa que este comando se comporta como esperas, incluso sin comillas.
if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi
[[ admite todas las expresiones condicionales que test y [ pueden manejar.
Además, [[ ofrece
=~ de coincidencia con expresiones regulares,== y != como operador de coincidencia con patrones glob,&& y || como operadores lógicos (regla especial de análisis sintáctico),< y > como operadores de comparación de strings «directos» (regla especial de análisis sintáctico: como son símbolos de redirección, en [ hay que escaparlos).Se considera ampliamente que estas características especiales ofrecen tantos beneficios que [[ se debería usar de forma exclusiva.
(Por ejemplo, la Google Shell Style Guide.)
case es otro comando de control de flujo.
Es como una sentencia «switch» en otros lenguajes.
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
WORD se compara con cada PATTERN. Cuando uno coincide, se ejecutan los COMMANDS.
read -p "Guess the secret word: " word
case "$word" in
secret) echo "Yes, you guessed it!" ;;
??????) echo "That's the right number of letters." ;;
s*) echo "You guessed the first letter." ;;
*) echo "Not even close! Try again." ;;
esac
Cada cláusula COMMANDS debe terminar con dos puntos y coma, ;;.