Bash: doble igual vs -eq

47

Estoy haciendo una comparación de enteros en bash (tratando de ver si el usuario se está ejecutando como root), y encontré dos formas diferentes de hacerlo:

Doble igual:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Entiendo que no hay> = o <= en bash, solo -ge y -le, entonces ¿por qué hay un ==si hay un -eq?

¿Hay alguna diferencia en la forma en que compara ambos lados?

beatgammit
fuente
3
Tenga en cuenta que se requieren espacios entre paréntesis: [ $UID -eq 0 ]no [ $UID -eq 0].
Gilles 'SO- deja de ser malvado'

Respuestas:

51

==es un bashalias específico para =, que realiza una comparación de cadena (léxica) en lugar de la -eqcomparación numérica. (Está al revés desde Perl: los operadores de estilo de palabra son numéricos, los simbólicos son léxicos).

geekosaur
fuente
¿Significa eso que si ambos lados son enteros, los convierte a ambos lados en cadenas y luego los compara?
beatgammit
55
Más precisamente, es al revés: todo es una cadena, -eqle dice bashque interprete las cadenas como enteros (produciendo 0sin advertencia si una cadena no es numérica).
geekosaur
11
@tjameson Para dar un ejemplo: [ 01 -eq 1 ]pero [ 01 != 1 ].
Gilles 'SO- deja de ser malvado'
3
Nótese que si bien ==como un [operador no es estándar y no debe ser utilizado, no es específica de Bash . Fue introducido por ksh y también es compatible con zsh (aunque =es necesario citar el primero ), yash y la [utilidad GNU (y cualquiera de esas utilidades implementadas como scripts ksh en algunos sistemas) al menos).
Stéphane Chazelas
@geekosaur Recibo una advertencia de bash v4.3.42 si mi cadena no es numérica: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: hello: expresión entera esperada
Andrew Bainbridge
13

Para elaborar sobre la respuesta de Bollovan ...

No existe >=o <=operador de comparación de cadenas. Pero podría usarlos con el ((...))comando aritmético para comparar enteros.

También puede utilizar los otros operadores de comparación de cadenas ( ==, !=, <, >, pero no =) para comparar números enteros si se utilizan en el interior ((...)).

Ejemplos

  • Ambas [[ 01 -eq 1 ]]y (( 01 == 1 ))hacen comparaciones enteras. Ambas son ciertas.
  • Ambos [[ 01 == 1 ]]y [ 01 = 1 ]hacer comparaciones de cuerdas. Ambos son falsos.
  • Ambos (( 01 -eq 1 ))y (( 01 = 1 ))devolverá un error.

Nota: la sintaxis de [[...]]paréntesis doble y la sintaxis de paréntesis dobles ((...))no son compatibles con todos los shells.

toxalot
fuente
1
Tenga en cuenta que (excepto para mksh/ zsh(excepto en modo POSIX (aunque no es una función POSIX))), (( 010 == 10 ))devolvería falso porque se 010trataría como un número octal (8 en decimal).
Stéphane Chazelas
Tenga en cuenta que mientras que la mayoría test/ [implementaciones no tienen >=/ <=operadores ( yash's [tiene sin embargo), exprtiene este tipo de operadores, a pesar de que va a hacer la comparación aritmética si los argumentos son reconocidos como números ( expr 01 '>=' 1devuelve true, expr X01 '>=' X1devuelve False).
Stéphane Chazelas
7

Si desea hacer una comparación de enteros, usará mejor (()), donde también puede usar> = etc.

Ejemplo:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
bollovan
fuente
O (( UID == 0 ))o (( ! UID ))para eso importa. Tenga en cuenta que ((...))no es estándar (una kshcaracterística también compatible con bashy zshcon variaciones).
Stéphane Chazelas