2010-08-05 4 views
121

Mon code:[: opérateur inattendu dans la programmation 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 

Mais quand j'exercerai me invite du terminal

sh ./choose.sh 

que

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

Y at-il une erreur dans mon script bash ? Merci!

+0

Lorsque j'ai exécuté le même code sous Linux et dans cygwin, je n'obtenais aucune erreur – Raghuram

+2

Cygwin a probablement alias 'sh' à' bash'. Certaines distributions n'offrent plus un vrai 'sh'. Bien que certains diront (et je suis plutôt d'accord) que si vous écrivez un script pour être portable, écrivez-le dans 'sh' au lieu de' bash'. – Wolph

+0

Mon problème était que j'avais besoin de 'source foobar.sh' pas'./Foobar.sh' – jsta

Répondre

215

Il n'y a pas d'erreur dans votre bash scénario. Mais vous exécutez avec sh qui a une syntaxe moins étendue;)

Alors, exécutez bash ./choose.sh à la place :)

+2

Résoudre mon problème.Merci! Y a-t-il une différence entre la commande "sh" et "bash"? –

+3

La syntaxe 'bash' est un sur-ensemble de la syntaxe' sh' - l'exécutable '/ bin/sh' de votre système peut fournir uniquement la fonctionnalité' sh' standard, dans laquelle les tests '[]' ne sont pas inclus. – Tim

+10

Oui. Ce sont des coquilles complètement différentes. Bien que bash ait été basé sur sh, et soit en grande partie rétrocompatible avec lui, il se peut que ce soit le même programme sur votre système, mais il se comportera différemment selon le nom que vous utilisez. Vous pouvez faire exécuter automatiquement le script avec bash en changeant la première ligne en '#!/Bin/bash' et en rendant le fichier exécutable, et en exécutant'./Choose.sh'. –

5

vous devez utiliser bash à la place ou de réécrire votre script en utilisant sh norme

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

Je pense qu'il est plus pratique d'utiliser "[]" au lieu de "test". Il semblait que "bash ./choose.sh" pouvait résoudre le problème. –

+0

@kit de toute façon, sh est plus petit portable – Anycorn

+3

@ kit.yang Comment les supports sont-ils plus pratiques? La confusion historique causée par le fait que les gens ne réalisent pas que [est synonyme de test et que les erreurs continues dues aux espaces omis autour des parenthèses compense à peine le caractère unique enregistré. ("if [$ x = 5]" vs "si test $ x = 5", 13 caractères contre 14). –

2

Pour l'exécuter avec Bash, utilisez #/bin/bash et chmod à être! exécutable, puis utilisez

./choose.sh 
192

Posix sh ne comprend pas == pour l'égalité des cordes, comme c'est un bash isme. Utilisez = à la place.

Les autres personnes qui disent que les crochets ne sont pas pris en charge par sh se trompent, btw.

+4

Oui, j'essaye juste de remplacer le "==" pour "=", le script peut également être exécutif par "sh ./choose.sh". Les deux bash et sh supportent les parenthèses. –

+25

+1 C'est une meilleure réponse que d'utiliser inutilement bash, IMO. –

+4

donnez à cet homme un cookie! – tbking

1

En fait le "[" carré d'ouverture carré est juste un alias de shell interne pour la commande de test.

On peut donc dire:

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

ou

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

... ils sont équivalents dans les deux sh ou bash. Notez l'exigence d'avoir une parenthèse fermante "]" sur la commande "[" mais autre que "[" est la même chose que "test". "test de l'homme" est une bonne chose à lire.

+0

'man test' est la page de manuel de/bin/test pas pour la fonction shell intégrée – stew

+0

' ls $ (qui [) ' donne '/ usr/bin/[' –

5

vous pouvez utiliser le cas/ESAC au lieu de if/else

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

Ne pas utiliser un mot clé réservé comme le début d'un nom de variable: par exemple HOSTNAME échouera comme HOST {TYPE | NOM} sont réservés

21

Dans votre code remplacez cette ligne:

#!/bin/sh 

avec

#!/bin/bash 

Ceci doit être la première ligne de votre script et indique quel shell linux doit être utilisé. sh ne supporte pas les mêmes commandes que bash.

+0

Ceci devrait être marqué comme la bonne réponse. – MaxZoom