Bash
Expresiones condicionales
Buscar..
Sintaxis
- [[-OP $ nombre de archivo]]
- [[$ file1 -OP $ file2]]
- [[-z $ cadena]]
- [[-n $ cadena]]
- [["$ string1" == "$ string2"]]
- [["$ string1" == $ patrón]]
Observaciones
La sintaxis [[ … ]]
rodea a las expresiones condicionales incorporadas de bash. Tenga en cuenta que se requieren espacios en ambos lados de los soportes.
Las expresiones condicionales pueden usar operadores unarios y binarios para probar las propiedades de cadenas, enteros y archivos. También pueden usar los operadores lógicos &&
, ||
y !
.
Comparacion de archivos
if [[ $file1 -ef $file2 ]]; then
echo "$file1 and $file2 are the same file"
fi
"Mismo archivo" significa que la modificación de uno de los archivos en su lugar afecta al otro. Dos archivos pueden ser iguales incluso si tienen nombres diferentes, por ejemplo, si son enlaces duros, o si son enlaces simbólicos con el mismo objetivo, o si uno es un enlace simbólico que apunta al otro.
Si dos archivos tienen el mismo contenido, pero son archivos distintos (para que la modificación de uno no afecte al otro), -ef
reporta como diferentes. Si desea comparar dos archivos byte a byte, use la utilidad cmp
.
if cmp -s -- "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
echo "$file1 and $file2 differ"
fi
Para producir una lista legible por humanos de diferencias entre archivos de texto, use la utilidad diff
.
if diff -u "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
: # the differences between the files have been listed
fi
Pruebas de acceso a archivos
if [[ -r $filename ]]; then
echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
echo "$filename is an executable file"
fi
Estas pruebas toman en cuenta los permisos y la propiedad para determinar si el script (o los programas iniciados desde el script) pueden acceder al archivo.
Cuidado con las condiciones de la carrera (TOCTOU) : solo porque la prueba sea exitosa ahora no significa que aún sea válida en la siguiente línea. Por lo general, es mejor intentar acceder a un archivo y manejar el error, en lugar de probar primero y luego tener que manejar el error de todos modos en caso de que el archivo haya cambiado mientras tanto.
Comparaciones numericas
Las comparaciones numéricas utilizan los operadores -eq
y amigos.
if [[ $num1 -eq $num2 ]]; then
echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
echo "$num1 <= $num2"
fi
Hay seis operadores numéricos:
-
-eq
igual -
-ne
es igual -
-le
menos o igual -
-lt
menos que -
-ge
mayor o igual -
-gt
mayor que
Tenga en cuenta que los operadores <
y >
dentro de [[ … ]]
comparan cadenas, no números.
if [[ 9 -lt 10 ]]; then
echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
echo "9 is after 10 in lexicographic order"
fi
Los dos lados deben ser números escritos en decimal (o en octal con un cero inicial). Alternativamente, use la sintaxis de expresión aritmética ((…))
, que realiza cálculos de enteros en una sintaxis similar a C / Java / ...
x=2
if ((2*x == 4)); then
echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"
Comparación de cadenas y emparejamiento
La comparación de cadenas utiliza el operador ==
entre cadenas citadas . El operador !=
Niega la comparación.
if [[ "$string1" == "$string2" ]]; then
echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
echo "\$string1 and \$string2 are not identical"
fi
Si no se cita el lado derecho, entonces es un patrón de comodín con el que se $string1
.
string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
# the test is true
echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
# the test is false
echo "The string $string does not match the pattern $pattern"
fi
Los operadores <
y >
comparan las cadenas en orden lexicográfico (no hay operadores menos o iguales o mayores o iguales para las cadenas).
Hay pruebas unarias para la cadena vacía.
if [[ -n "$string" ]]; then
echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
echo "$string is empty"
fi
Arriba, la comprobación -z
puede significar que $string
no está establecida, o está configurada en una cadena vacía. Para distinguir entre vacío y no definido, use:
if [[ -n "${string+x}" ]]; then
echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
echo "$string is set to an empty string"
fi
donde x
es arbitrario. O en forma de tabla :
+-------+-------+-----------+
$string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]] | true | true | false |
| [[ -z ${string+x} ]] | true | false | false |
| [[ -z ${string-x} ]] | false | true | false |
| [[ -n ${string} ]] | false | false | true |
| [[ -n ${string+x} ]] | false | true | true |
| [[ -n ${string-x} ]] | true | false | true |
+-----------------------+-------+-------+-----------+
Alternativamente , el estado se puede verificar en una declaración de caso:
case ${var+x$var} in
(x) echo empty;;
("") echo unset;;
(x*[![:blank:]]*) echo non-blank;;
(*) echo blank
esac
Donde [:blank:]
es la ubicación específica de caracteres espaciados horizontales (tabulación, espacio, etc.).
Pruebas de tipo de archivo
El operador condicional -e
comprueba si existe un archivo (incluidos todos los tipos de archivos: directorios, etc.).
if [[ -e $filename ]]; then
echo "$filename exists"
fi
También hay pruebas para tipos de archivos específicos.
if [[ -f $filename ]]; then
echo "$filename is a regular file"
elif [[ -d $filename ]]; then
echo "$filename is a directory"
elif [[ -p $filename ]]; then
echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
echo "$filename is a named socket"
elif [[ -b $filename ]]; then
echo "$filename is a block device"
elif [[ -c $filename ]]; then
echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
echo "$filename is a symbolic link (to any file type)"
fi
Para un enlace simbólico, aparte de -L
, estas pruebas se aplican al objetivo y devuelven falso para un enlace roto.
if [[ -L $filename || -e $filename ]]; then
echo "$filename exists (but may be a broken symbolic link)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename is a broken symbolic link"
fi
Prueba de estado de salida de un comando
Estado de salida 0: éxito
Estado de salida distinto de 0: error
Para probar el estado de salida de un comando:
if command;then
echo 'success'
else
echo 'failure'
fi
Una prueba de línea
Puedes hacer cosas como esta:
[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'
Una prueba de línea para el estado de salida:
command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1