Expresiones condicionales en Bash Shell
Bash como lenguaje de programación no es el recurso de la mayoría de los programadores, especialmente con lenguajes mucho más comunes como Python y C.
Es útil escribir construcciones de programación para ejecutar comandos basados en criterios con declaraciones if o el mismo comando con múltiples argumentos usando un bucle for
.
Este tutorial repasará las declaraciones if en Bash, centrándose en los tipos de expresiones condicionales que se usan en las declaraciones if.
La declaración if
en Bash
La sintaxis general de la instrucción if
en Bash es la siguiente.
if condition; then
do-if-true;
elif second-condition; then
do-else-if-true
elif third-condition; then
do-else-if-third-true
else
do-else-false
fi
Las propias condiciones pueden tener una sintaxis diferente, dependiendo de la condición requerida.
- Si desea utilizar la salida de un comando como condición, como
grep
el contenido de un archivo para ver si contiene una determinada subcadena, puede colocar el comando después de la palabra clave if, de la siguiente manera.
if greq -q "string" file.txt; then
echo "string exists in file.txt."
else
echo "string does not exist in file.txt."
fi
[ "$s" = "string" ]
comprueba si la variable$s
contiene el valorcadena
. También es equivalente atest "$s" = "string"
, dondetest
sustituye efectivamente a los corchetes.
if [ "$s" = "string" ]; then
echo "string is equivalent to \$s"
else
echo "string is not equivalent to \$s"
fi
-
Incluso puede realizar operaciones aritméticas, como verificar si el número esperado de archivos o líneas en un archivo es cierto o si el número en un directorio es menor o mayor que el de otro directorio.
Hacemos esto con pares de paréntesis.
a=$(ls dir_a | wc -l)
b=$(ls dir_b | wc -l)
if (( a < b )); then
echo "Directory a has fewer files than directory b."
elif (( a > b )); then
echo "Directory a has more files than directory b."
else
echo "Directory a has the same number of files as that of directory b."
fi
Condicionales Bash incorporados
A veces, ejecutar un programa separado para verificar algo tan simple como la existencia de archivos, las fechas de modificación y los tamaños es tedioso y consume muchos recursos, por lo que Bash puede verificar dichos atributos como declaraciones if directamente.
Las siguientes banderas verifican la existencia o inexistencia de estos atributos, devolviendo un resultado verdadero o falso a la declaración if.
Por ejemplo, para verificar si un comando no produjo ningún resultado, podemos tratar su salida como una cadena y verificar si la longitud de esa cadena es cero con el indicador -z
, de la siguiente manera.
out=$(bash print-if-error.sh)
if [[ -z $out ]]; then
echo "The script ran successfully."
else
echo "The script produced the following errors: "
echo $out
fi
Para obtener el inverso de la condición, puede usar el !
NOT, o use la forma inversa de esta bandera, que es -n
, o ninguna bandera, ya que una cadena no vacía puede comportarse como true
en una instrucción if de Bash.
out=$(bash print-if-error.sh)
if [[ $out ]]; then
echo "The script produced the following errors: "
echo $out
else
echo "The script ran successfully."
fi
Algunas otras banderas útiles se explican a continuación, con explicaciones a las que se hace referencia en el Manual de referencia de GNU Bash.
-f
comprueba si el archivo existe y es un archivo normal.-d
comprueba si el argumento proporcionado era un directorio.-h
comprueba si el argumento proporcionado era un enlace simbólico.-s
comprueba si el archivo existe y no está vacío.-r
comprueba si el archivo es legible.-w
comprueba si el archivo es escribible.-x
comprueba si el archivo es ejecutable.
Para las banderas que toman dos argumentos, como los operadores de comparación, el primer argumento viene antes de la bandera mientras que el segundo aparece después de la bandera.
Supongamos que comparamos dos archivos, a.txt y b.txt, para ver cuál es más nuevo, con el indicador -nt
. El inverso comprobará si es más antiguo, con -ot
.
out=$(bash print-if-error.sh)
if [[ a.txt -nt b.txt ]]; then
echo "a.txt is newer than b.txt."
else
echo "a.txt is older or the same age as b.txt."
fi
Otras banderas de dos operandos son las siguientes.
-ef
asegura que los dos argumentos se refieran al mismo dispositivo y números de inodo.!=
asegura que los dos argumentos no sean iguales.<
comprueba que el primer argumento está alfabéticamente antes del segundo.>
comprueba que el primer argumento está alfabéticamente después del segundo.-eq
asume que ambos argumentos son enteros y comprueba que son iguales.-ne
asume que ambos argumentos son enteros y comprueba que no son iguales.-lt
asume que ambos argumentos son enteros y comprueba que el primero es menor que el segundo. Se puede usar-le
para comprobar si son iguales.-gt
asume que ambos argumentos son enteros y comprueba que el primero es mayor que el segundo. Se puede usar-ge
para comprobar si son iguales.