2010-08-05 13 views
121

Mój kod:[: Nieoczekiwany operator w programowaniu powłoki

#!/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 

Ale kiedy wykonać

sh ./choose.sh 

Terminal zapyta mnie, że

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

Czy jest jakiś błąd w moim skrypcie bash ? Dzięki!

+0

Kiedy zrobiłem ten sam kod w Linuksie iw cygwin nie miałem żadnych błędów – Raghuram

+2

Cygwin najprawdopodobniej użył aliasu 'sh' na' bash'. Niektóre dystrybucje nie oferują już prawdziwego 'sh'. Chociaż niektórzy będą się spierać (i mam tendencję do wyrażenia zgody), że jeśli piszesz skrypt, który ma być przenośny, zapisz go w 'sh' zamiast' bash'. – Wolph

+0

Mój problem polegał na tym, że potrzebowałem 'source foobar.sh' not'./Foobar.sh' – jsta

Odpowiedz

215

Nie ma błędu w bash skryptu. Ale realizujemy je sh który ma mniej rozległe składni;)

Więc, zamiast uruchomić bash ./choose.sh :)

+2

Rozwiąż mój problem. Dzięki! Czy jest jakaś różnica między poleceniem "sh" i "bash"? –

+3

'bash' syntax to nadzbiór składni' sh' - plik '/ bin/sh' w Twoim systemie może udostępniać tylko standardową funkcję' sh', w której nie uwzględniono testów w stylu []. – Tim

+10

Tak. Są to zupełnie inne muszle. Mimo że bash był oparty na i jest w dużej mierze kompatybilny wstecz z sh, i może to być faktycznie ten sam program w twoim systemie, ale nadal będzie się zachowywał inaczej, w zależności od tego, z której nazwy korzystasz. Możesz uruchomić skrypt z bashem automatycznie, zmieniając pierwszy wiersz na '#!/Bin/bash' i robiąc plik wykonywalny, i po prostu uruchamiając'./Choose.sh'. –

5

trzeba zamiast używać bash lub przepisać skrypt przy użyciu standardowego sh

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

Myślę, że wygodniej jest użyć "[]" zamiast "testu". Wyglądało na to, że "bash ./choose.sh" może rozwiązać problem. –

+0

"tak czy siak, sh jest bardziej mały przenośny – Anycorn

+3

@ kit.yang Jak są bardziej wygodne konsole? Historyczne zamieszanie spowodowane przez ludzi, którzy nie zdają sobie sprawy, że [jest synonimem testu i ciągłe błędy popełniane przez pominięte białe znaki w nawiasach, nie rekompensują pojedynczego znaku zapisanego. ("if [$ x = 5]" vs "jeśli test x = 5", 13 znaków vs 14). –

2

Aby go wykonać z Bash, użyć #!/Bin/bash i chmod go mieć! wykonywalny, a następnie użyć

./choose.sh 
192

POSIX sh nie rozumie == równości smyczkowego, jako że jest bash -izm. Zamiast tego użyj =.

Inne osoby, które twierdzą, że nawiasy nie są obsługiwane przez sh są nieprawidłowe, btw.

+4

Tak, staram się po prostu zastąpić "==" dla "=", skryptem może być także wykonanie przez "sh ./choose.sh". Zarówno bash, jak i sh wspierają nawiasy. –

+25

+1 To jest lepsza odpowiedź niż niepotrzebnie przy użyciu basha, IMO. –

+4

daj temu człowiekowi ciasteczko! – tbking

1

W rzeczywistości "[" kwadratowy nawias otwierający jest po prostu wewnętrznym aliasem powłoki dla polecenia testowego.

Więc można powiedzieć:

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

lub

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

... są równoważne albo sh lub bash. Zwróć uwagę na wymóg posiadania nawiasu zamykającego "]" w komendzie "[", ale poza tym "[" jest takie samo, jak "test". "test man" jest dobrą rzeczą do przeczytania.

+0

'test man' jest stroną podręczną/bin/test nie dla wbudowanej funkcji powłoki – stew

+0

' ls $ (która [) ' daje '/ usr/bin/[' –

5

można użyć sprawę/ESAC zamiast if/else

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

nie wolno używać zastrzeżonego słowa kluczowego jako początek każdej nazwy zmiennej: np hostname fail jako gospodarz {rodzaju | NAME} są zarezerwowane

21

W kodzie zastąpić ten wiersz:

#!/bin/sh 

z

#!/bin/bash 

To musi być pierwsza linia twojego skryptu i wskazuje, którą powłokę linux trzeba użyć. sh nie obsługuje tych samych poleceń co bash.

+0

To powinno być oznaczone jako poprawna odpowiedź. – MaxZoom

Powiązane problemy