Estoy haciendo una comparación de enteros en bash (tratando de ver si el usuario se está ejecutando como root), y encontré dos diferentes formas de hacerlo:
Doble es igual a:
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 «sa -eq
?
¿Hay alguna diferencia en la forma en que compara ambos lados?
Comentarios
Respuesta
==
es un bash
-alias específico para =
, que realiza una comparación de cadenas (léxica) en lugar de la -eq
comparación numérica. (Es al revés de Perl: los operadores de estilo de palabra son numéricos, los simbólicos léxicos.)
Comentarios
- ¿Eso significa que si ambos lados son números enteros, convierte ambos lados en cadenas y luego las compara?
- Más precisamente ' es al revés: todo es una cadena,
-eq
le dice abash
que interprete las cadenas como enteros (produciendo0
sin una advertencia si una cadena isn ' t numérico). - @tjameson Para dar un ejemplo:
[ 01 -eq 1 ]
pero[ 01 != 1 ]
. - Tenga en cuenta que aunque
==
como operador[
no es estándar y debe no se puede usar, no es específico de bash . Fue introducido por ksh y también es compatible con zsh (aunque es necesario citar el primer=
) , yash y la utilidad GNU[
( y cualquier utilidad implementada como scripts ksh en algunos sistemas) al menos). - @geekosaur Recibo una advertencia de bash v4.3.42 si mi cadena no es ' t numérico:
$ if [ "hello" -eq 0 ]; then echo true; fi
bash: [: hola: se espera una expresión entera
Respuesta
Para ampliar la respuesta de bollovan …
No hay >=
o <=
operador de comparación para cadenas. Pero puede usarlos con el comando aritmético ((...))
para comparar enteros.
También puede usar los otros operadores de comparación de cadenas (==
, !=
, <
, >
, pero no =
) para comparar enteros si los usa dentro de ((...))
.
Ejemplos
- Tanto
[[ 01 -eq 1 ]]
y(( 01 == 1 ))
son números enteros comparaciones. Ambos son verdaderos. - Tanto
[[ 01 == 1 ]]
como[ 01 = 1 ]
realizan comparaciones de cadenas. Ambos son falsos. - Tanto
(( 01 -eq 1 ))
como(( 01 = 1 ))
devolverán un error.
Nota: La sintaxis de corchetes dobles [[...]]
y la sintaxis de paréntesis dobles ((...))
no son compatibles con todos los shells.
Comentarios
- Tenga en cuenta que (excepto
mksh
/zsh
(excepto en el modo POSIX (aunque ' no es una función POSIX))),(( 010 == 10 ))
devolvería falso porque010
se trataría como un número octal (8 en decimal). - Tenga en cuenta que aunque la mayoría de
test
/[
las implementaciones no ' no tienen operadores>=
/<=
(yash
' s[
tiene),expr
tiene tales operadores, aunque hará ar comparación tmética si los argumentos se reconocen como números (expr 01 '>=' 1
devuelve verdadero,expr X01 '>=' X1
devuelve falso).
Respuesta
Si desea hacer una comparación de enteros, será mejor que use (()), donde también puede usar> = etc.
Ejemplo:
if (( $UID == 0 )); then echo "You are root" else echo "You are not root" fi
Comentarios
- O
(( UID == 0 ))
o(( ! UID ))
para eso. Tenga en cuenta que((...))
no es estándar (una funciónksh
también es compatible conbash
yzsh
con variaciones).
[ $UID -eq 0 ]
, no[ $UID -eq 0]
.