it-swarm.dev

Comparar entero en bash, se espera un operador unario

El siguiente código da

[: -ge: se espera un operador unario

cuando

i=0

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

¿por qué?

128
Filip Ekberg

Su problema surge del hecho de que $i tiene un valor en blanco cuando su declaración falla. Siempre cite sus variables al realizar 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. Supongamos el ejemplo original,

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

Lo primero que hace el Shell al ejecutar esa línea de código en particular es sustituir el valor de $i, tal como lo haría la función buscar y reemplazar de su editor favorito. Entonces, asuma que $i está vacío o, aún más ilustrativo, ¡asuma que $i es un montón de espacios! El Shell reemplazará $i de la siguiente manera:

if [     -ge 2 ] ; then ...

Ahora que se han realizado las sustituciones de variables, el Shell continúa con la comparación y ... falla porque no puede ver nada inteligible para el 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 omitirá la if.

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

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

Esto sustituirá el valor 0 en lugar de $i is $i no está definido. Todavía mantengo las citas porque, una vez más, si $i es un montón de espacios en blanco, entonces no cuenta como no definido, no se reemplazará con 0, y volverá a encontrar el problema.

Por favor lea este cuando tenga tiempo. La Shell es tratada como una caja negra por muchos, pero opera con muy pocas y muy simples reglas: una vez que esté consciente de cuáles son esas reglas (una de ellas es cómo funcionan las variables en la Shell, como se explicó anteriormente), la Shell No tienes más secretos para ti.

279
vladr

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

6
starblue

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

Para las 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

6
Roman Newaza

Su pieza de guión funciona muy bien. ¿Está seguro de que no está asignando nada más antes de if a "i"?

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

2