Bash no tiene el concepto de valores booleanos. Hay strings y números, y arrays de strings o números. Entonces, ¿cómo tratan 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 incluidos. Bash considera que un estado de salida cero representa éxito. Cualquier otro estado de salida representa fracaso.
Esto se 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 por if; los comandos de la condición se separan de los comandos «de éxito» con then; y termina con fi.
La cláusula else es opcional.
CONDITIONAL_COMMANDS puede ser un único comando o puede ser una lista de comandos.
Se ejecutan los CONDITIONAL_COMMANDS y
Se pueden escribir 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 insistir: 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 ninguna sintaxis especial en torno a los CONDITIONAL_COMMANDS. Puede que estés acostumbrado a ver instrucciones if con este aspecto:
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 fracaso.
Como en todos los comandos, se requiere un espacio en blanco entre él y sus argumentos.
En realidad, [ es un sinónimo del comando test.
Son exactamente lo mismo, salvo 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; se enumeran en la sección Expresiones condicionales de Bash del manual.
En los ejemplos anteriores, fíjate en que todas las variables están entrecomilladas.
Los comandos test y [ son comandos normales, en los que los argumentos están sujetos a la división de palabras y a la expansión de nombres de archivo como en cualquier otro comando.
Es importante 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 entrecomillar:
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
La construcción condicional [[...]] no es un comando, es una palabra clave.
Esto significa que, aunque se trata 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 entrecomillar.
if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi
[[ admite todas las expresiones condicionales que pueden manejar test y [.
Además, [[ ofrece
=~,== y !=, que funcionan como operador de coincidencia de patrones glob,&& y || como operadores lógicos (regla de análisis sintáctico especial),< y > como operadores de comparación de strings «a secas» (regla de análisis sintáctico especial: como son símbolos de redirección, en [ hay que escaparlos).Se considera ampliamente que estas características especiales aportan tantas ventajas que debería usarse [[ de forma exclusiva.
(Por ejemplo, la Google Shell Style Guide).
case es otro comando de control de flujo.
Es como una instrucción «switch» de otros lenguajes.
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
La WORD se compara con cada PATTERN. Cuando una 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 de COMMANDS debe terminar con dos puntos y coma, ;;.