2010-08-05 20 views
121

Mi código:[: operador inesperado en la programación del shell

#!/bin/sh 
    #filename:choose.sh 
    read choose 
    [ "$choose" == "y" -o "$choose" == "Y" ] && echo "Yes" && exit 0 
    [ "$choose" == "n" -o "$choose" == "N" ] && echo "No" && exit 0 
    echo "Wrong Input" && exit 0 

Pero cuando ejecuto

sh ./choose.sh 

terminal de mi mensaje que

[: 4: n: :Unexpected operator 
    [: 5: n: :Unexpected operator 

¿Hay algún error en mi escritura del golpe ? Gracias!

+0

Cuando ejecuté el mismo código en Linux y en cygwin no estaba obteniendo ningún error – Raghuram

+2

Cygwin tiene muy probablemente un alias de 'sh' a' bash'. Algunas distribuciones ya no ofrecen una verdadera 'sh'. Aunque algunos argumentarán (y estoy de acuerdo) que si estás escribiendo un guión para ser portátil, escríbelo en 'sh' en lugar de' bash'. – Wolph

+0

Mi problema era que necesitaba 'source foobar.sh' not'./Foobar.sh' – jsta

Respuesta

215

No hay ningún error en su fiesta guión. Pero se está ejecutando con sh que tiene una sintaxis menos extensa;)

lo tanto, ejecuta bash ./choose.sh lugar :)

+2

Resuelve mi problema. ¡Gracias! Entonces, ¿hay alguna diferencia entre el comando "sh" y "bash"? –

+3

La sintaxis 'bash' es un superconjunto de la sintaxis' sh' - el ejecutable '/ bin/sh' en su sistema puede proporcionar solo la funcionalidad estándar' sh', en la cual las pruebas '[]' -style no están incluidas. – Tim

+10

Sí. Son conchas completamente diferentes. Aunque, bash se basó en y es en gran parte compatible con SH, y en realidad podrían ser el mismo programa en su sistema, pero aún se comportarán de manera diferente dependiendo del nombre que use. Puede hacer que el script se ejecute automáticamente con bash cambiando la primera línea a '#!/Bin/bash' y haciendo el archivo ejecutable, y simplemente ejecutando'./Choose.sh'. –

5

se tienen que utilizar en lugar de bash o reescribir su guión usando sh estándar

sh -c 'test "$choose" = "y" -o "$choose" = "Y"' 
+0

Creo que es más conveniente usar "[]" en lugar de "prueba". Parecía que "bash ./choose.sh" puede resolver el problema. –

+0

@kit de cualquier manera, sh es más poco portátil – Anycorn

+3

@ kit.yang ¿Cómo son los brackets más convenientes? La confusión histórica causada por personas que no se dan cuenta de que [es un sinónimo de prueba y los continuos errores cometidos a través de espacios en blanco omitidos alrededor de los corchetes difícilmente compensan el único carácter guardado. ("if [$ x = 5]" vs "if test $ x = 5"; 13 chars vs 14). –

2

Para ejecutarlo con Bash, el uso #/bin/bash y chmod que sea! ejecutable, a continuación, utilizar

./choose.sh 
192

POSIX sh no entiende == para la igualdad de cadenas, ya que es una fiesta de ismo. Use = en su lugar.

Las otras personas que dicen que los corchetes no son compatibles con sh son incorrectos, por cierto.

+4

Sí, intento simplemente reemplazar el "==" por "=", el script también puede ser ejecutivo por "sh ./choose.sh". Tanto bash como sh admiten los corchetes. –

+25

+1 Esta es una mejor respuesta que usar innecesariamente bash, IMO. –

+4

¡dale una galleta a este hombre! – tbking

1

De hecho, el "cuadrado de apertura de ["] es solo un alias de shell interno para el comando de prueba.

Así que usted puede decir:

test -f "/bin/bash" && echo "This system has a bash shell" 

o

[ -f "/bin/bash" ] && echo "This system has a bash shell" 

... que son equivalentes, ya sea en sh o bash. Tenga en cuenta el requisito de tener un corchete "]" de cierre en el comando "[", pero aparte de eso "[" es lo mismo que "prueba". "prueba de hombre" es algo bueno de leer.

+0

'man test' es la página de manual de/bin/test no para la función de shell incorporada – stew

+0

' ls $ (which [) ' da '/ usr/bin/[' –

5

puede utilizar la caja/ESAC en lugar de if/else

case "$choose" in 
    [yY]) echo "Yes" && exit;; 
    [nN]) echo "No" && exit;; 
    *) echo "wrong input" && exit;; 
esac 
-2

No utilice ninguna palabra clave reservada como el inicio de cualquier nombre de variable: por ejemplo HOSTNAME fallará como anfitrión {TIPO | NOMBRE} están reservados

21

En su código de reemplazar esta línea:

#!/bin/sh 

con

#!/bin/bash 

Esta debe ser la primera línea de su script e indica qué shell de linux debe usarse. sh no admite los mismos comandos que bash.

+0

Esto debería marcarse como la respuesta correcta. – MaxZoom

Cuestiones relacionadas