%20en%20las%20comparaciones%20de%20shell%3F.png)
Lea que para comparar cadenas internas if
necesitamos usar corchetes dobles. Algunos libros dicen que la comparación se puede hacer mediante =
. Pero también funciona con el ==
.
#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
echo "equal"
fi
¿Hay alguna diferencia entre =
y ==
en la comparación?
Respuesta1
En bash
(como en ksh
donde bash
se copió esa sintaxis), [[ $a == $b ]]
no es comparación, es coincidencia de patrones. Necesita [[ $a == "$b" ]]
una comparación de igualdad de byte a byte. =
es el mismo que ==
en cualquier shell que admita [[...]]
.
[[...]]
no es sh
una sintaxis estándar. El[
dominioes estándar, y el estándarcomparaciónoperador existe =
(aunque algunas [
implementaciones también reconocen ==
¹).
Al igual que en cualquier argumento de cualquier comando, las expansiones de variables deben citarse para evitardividir+globoy eliminación vacía (solo esta última se realiza en zsh
), por lo que:
[ "$a" = "$b" ]
En estándar sh
, la coincidencia de patrones se realiza con case
:
case $a in
($b) ...
esac
Para completar, otrossimilar a la igualdadoperadores que puede encontrar en los scripts de shell:
[ "$a" -eq "$b" ]
:[
operador estándar para comparar números enteros decimales. Algunas[
implementaciones permiten espacios en blanco alrededor de los números, otras permiten expresiones aritméticas arbitrarias, pero eso no es portátil. De forma portátil, se puede utilizar[ "$(($a))" -eq "$(($b))" ]
para eso. Vea también[ "$((a == b))" -ne 0 ]
cuál sería el equivalente estándar (excepto en POSIXly, el comportamiento solo se especifica si$a
contiene$b
constantes enteras) de:((a == b))
, de ksh y también encontrado enzsh
ybash
, devuelve verdadero si la evaluación de la expresión aritmética almacenada en$a
arroja el mismo número que la de$b
. Normalmente, se utiliza para comparar números. Tenga en cuenta que existen variaciones entre shells en cuanto a cómo se evalúan las expresiones aritméticas y qué números se admiten (por ejemplo, bash y algunas implementaciones/versiones de ksh no admiten punto flotante ni tratan los números con ceros a la izquierda como octales).expr "$a" = "$b"
realiza una comparación de números si ambos operandos se reconocen como números enteros decimales (algunos permiten espacios en blanco alrededor del número) y, en caso contrario, comprueba si los dos operandos de cadena tienen el mismo orden de clasificación. También fallaría para valores de$a
o$b
que seanexpr
operadores como(
,substr
...awk -- 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b"
: si$a
y$b
se reconocen como números (al menos números decimales enteros y de coma flotante como 1.2, -1.5e-4, se ignoran los espacios en blanco iniciales y finales, algunos también reconocen hexadecimal, octal o cualquier cosa reconocida porstrtod()
), entonces se realiza una comparación numérica. De lo contrario, dependiendo de la implementación, es una comparación de cadenas de byte a byte, oexpr
unastrcoll()
comparación, es decir, si$a
ordena$b
lo mismo.
Ver también:
¹ que incluye GNU [
y la [
versión integrada de ksh
, bash
, yash
algunos, aunque no todos, ash
shells basados y zsh
, sin embargo, tenga en cuenta que en zsh
,=cmd
es un operador de expansión de nombre de archivo especial(expandido en los mismos contextos que ~user
está) que se expande a la ruta del comando correspondiente, por lo que allí, a menos que desactive la equals
opción para deshabilitar esa característica, deberá escribirla [ "$a" '==' "$b" ]
o obtendrá un error que indica que el =
comando no se encuentra. Igual por[ "$string" '=~' "$regexp" ]
Respuesta2
Estos son equivalentes en bash:
[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]
No es necesario citar las dos primeras variables $x. Bash realiza división de palabras y expansión de nombres de rutas dentro de [ pero no dentro de [[:
$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$
[[ $x = "$y" ]]
es una comparación de cadenas pero [[ $x = $y ]]
es una expresión de coincidencia de patrones:
$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0
-eq solo debe usarse con números enteros:
$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0
Ver tambiénBashFAQ/031: ¿Cuál es la diferencia entre prueba, [ y [[?.
Respuesta3
Ambos =
y ==
son operadores. En algunos lenguajes (como C) uno se usa para asignar un valor a una variable y el otro para comparar valores (resultado de expresiones aritméticas). De hecho, ambos operadores son exactamente eso dentro de la Evaluación Aritmética. A $((a=23))
es una tarea, a $((a==23))
es una comparación aritmética.
$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"
11 0 23 1
Pero dentro de las construcciones de prueba (todaspruebay[…]y[[…]]) ambos operadores pretenden significar lo mismo y realizar la misma operación.
Entonces, todas estas opciones:
test "$a" = "$b"
[ "$a" = "$b" ]
[[ "$a" = "$b" ]]
test "$a" == "$b"
[ "$a" == "$b" ]
[[ "$a" == "$b" ]]
Sonequivalente en el interiorintentopara probar la igualdad binaria (variables citadas). Si la variable correcta no está entre comillas, puede interpretarse como un patrón y compararse en consecuencia: como un patrón, no como una cadena literal.
Los operadores citados \=
y \==
también son equivalentes cuando se usan en prueba y […]
. Pero el operador citado \==
falla por dentro [[…]]
.
Para otros shells, los resultados varían (el resultado correcto debe ser Y -
(verdadero falso), un código de salida diferente de 0 (verdadero) y 1 (falso) se informa como falla con ¤
). Algunos shells fallan - -
(el código de salida es siempre 1).
| dash ksh bash zsh
test a = "$b" | Y - Y - Y - Y -
[ a = "$b" ] | Y - Y - Y - Y -
[[ a = "$b" ]] | ¤ ¤ Y - Y - Y -
test a == "$b" | ¤ ¤ Y - Y - - -
[ a == "$b" ] | ¤ ¤ Y - Y - - -
[[ a == "$b" ]] | ¤ ¤ Y - Y - Y -
test a \= "$b" | Y - Y - Y - Y -
[ a \= "$b" ] | Y - Y - Y - Y -
[[ a \= "$b" ]] | ¤ ¤ Y - - - - -
test a \== "$b" | ¤ ¤ Y - Y - Y -
[ a \== "$b" ] | ¤ ¤ Y - Y - Y -
[[ a \== "$b" ]] | ¤ ¤ Y - - - - -
Todas las opciones funcionan en ksh, los operadores entrecomillados fallan en bash y zsh (dentro de [[…]]
) y los operadores sin comillas \=
y \==
también fallan en zsh (fuera de [[…]]
).