Comparar entero en bash, operador unario esperado

137

El siguiente código da

[: -ge: operador unario esperado

cuando

i=0

if [ $i -ge 2 ]
then
    #some code
fi

¿por qué?

Filip Ekberg
fuente

Respuestas:

295

Su problema surge del hecho de que $itiene un valor en blanco cuando falla su declaración. Siempre cite sus variables cuando realice comparaciones si existe la menor posibilidad de que una de ellas esté vacía, por ejemplo:

if [ "$i" -ge 2 ] ; then
  ...
fi

Esto se debe a cómo el shell trata las variables. Asuma el ejemplo original,

if [ $i -ge 2 ] ; then ...

Lo primero que hace el shell cuando ejecuta esa línea de código particular es sustituir el valor de $i, tal como lo haría la función de búsqueda y reemplazo de su editor favorito . ¡Asuma que $iestá vacío o, aún más ilustrativo, asuma que $ies un montón de espacios! El shell se reemplazará de la $isiguiente manera:

if [     -ge 2 ] ; then ...

Ahora que se realizan las sustituciones variables, el shell continúa con la comparación y ... falla porque no puede ver nada inteligible a la izquierda de -gt. Sin embargo, citando $i:

if [ "$i" -ge 2 ] ; then ...

se convierte en:

if [ "    " -ge 2 ] ; then ...

El shell ahora ve las comillas dobles, y sabe que en realidad está comparando cuatro espacios en blanco con 2 y se saltará el if.

También tiene la opción de especificar un valor predeterminado para $isi $iestá en blanco, de la siguiente manera:

if [ "${i:-0}" -ge 2 ] ; then ...

Esto va a sustituir el valor 0 en lugar de $ique se $iestá definido. Todavía mantengo las comillas porque, de nuevo, si $ies un montón de espacios en blanco, entonces no cuenta como indefinido , no se reemplazará con 0, y se encontrará con el problema una vez más.

Por favor, lea esto cuando tenga tiempo. Muchos tratan el shell como una caja negra, pero funciona con muy pocas y muy simples reglas: una vez que sepa cuáles son esas reglas (una de ellas es cómo funcionan las variables en el shell, como se explicó anteriormente), el shell No tengo más secretos para ti.

vladr
fuente
77
La variable entre comillas generará un nuevo error como la expresión entera esperada
Néstor
@ Néstor incorrecto , citar una variable NO generará un nuevo error como la expresión entera esperada si la variable es numérica; proporcionar un valor variable no numérico, ya sea citado o no, dará como resultado dicho error.
vladr
6

A juzgar por el mensaje de error, el valor de i era la cadena vacía cuando la ejecutó, no 0.

starblue
fuente
6

Necesito agregar mis 5 centavos. Veo que todos usan [o [[, pero vale la pena mencionar que no son parte de la sintaxis if.

Para comparaciones aritméticas, use ((...))en su lugar.

((...)) es un comando aritmético, que devuelve un estado de salida de 0 si la expresión es distinta de cero, o 1 si la expresión es cero. También se usa como sinónimo de "let", si se necesitan efectos secundarios (asignaciones).

Ver: expresión aritmética

Roman Newaza
fuente
2

Tu guión funciona de maravilla. ¿Estás seguro de que no estás asignando nada más antes del if a "i"?

Un error común también es no dejar un espacio después y entre corchetes.

Fernando Miguélez
fuente