Z poniższego skryptu powłoki, dlaczego otrzymuję błędy
syntax error near unexpected token `else'
Skrypt powłoki
echo "please enter username"
read user_name
echo "please enter password"
read -s pass
echo ${ORACLE_SID}
SID=${ORACLE_SID}
if ["${ORACLE_SID}" != 'Test'] then
sqlplus -s -l $USER_NAME/$PASS@$SID <<EOF
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
EOF
else
echo "Cannot copy"
fi
Odpowiedzi:
Musisz zakończyć warunek w
if
ten sposób:lub tak:
Uwaga: musisz także wstawiać spacje
[
przed i przed]
.Powodem
;
lub podziałemif
wiersza jest to, że część warunku instrukcji jest tylko poleceniem. Dokładnie każde polecenie dowolnej długości. Powłoka wykonuje to polecenie, sprawdza status wyjścia polecenia, a następnie decyduje, czy wykonaćthen
część, czyelse
część.Ponieważ polecenie może mieć dowolną długość, musi istnieć znacznik do oznaczenia końca części warunku. To jest
;
lub nowa linia, po której następujethen
.Powodem spacji
[
jest to, że[
jest to polecenie. Zwykle wbudowane w powłokę. Powłoka wykonuje polecenie[
z resztą jako parametrami, w tym]
jako obowiązkowy ostatni parametr. Jeśli nie umieścisz spacji po[
tym, jak powłoka spróbuje wykonać[whatever
polecenie i zakończy się niepowodzeniem.Powód miejsca przed tym
]
jest podobny. Ponieważ w przeciwnym razie nie zostanie rozpoznany jako parametr sam w sobie.źródło
test.sh: line 6: [: missing
] ''if
jest składnią, to nie jest zwykłe polecenie. To zastrzeżone słowo. W przeciwieństwie do wielu innych języków programowania, powłoka nie wszędzie rozpoznaje słowa zastrzeżone, tylko gdy są one pierwszym słowem polecenia (z kilkoma subtelnościami).if
to jest składnia. Próbowałem zakomunikować, że część warunkuif
nie jest ograniczona do pewnej formy przez składnię. Zredagowałem tekst. Mam nadzieję, że teraz jest jaśniej.Możesz łatwo sprawdzić skrypty powłoki za pomocą ShellCheck online (dostępny również jako samodzielne narzędzie).
W takim przypadku będzie wskazywać, że instrukcja if wymaga spacji,
[
przed i przed]
, oraz że potrzebujesz;
(lub nowego wiersza) przedthen
tym samym wierszem.Kiedy to naprawisz, wyświetli się informacja, że
USER_NAME
jest używany bez inicjowania czegokolwiek. Jest tak, ponieważ masz równieżuser_name
zmienną (wielkość liter ma znaczenie). To samo dotyczyPASS
ipass
.Mówi ci również, abyś używał,
read -r
aby powstrzymać sięread
od zniekształcania\
(może to być ważne na przykład w przypadku haseł) oraz że powinieneś podwójnie cytować zmienne podczas wywoływania,sqlplus
aby zapobiec przypadkowemu globalizacji nazw plików i dzieleniu słów przez powłokę (ponownie jest to ważne, jeśli hasło zawiera na przykład znaki globowania plików, takie jak*
spacje).Wcięcie kodu sprawi, że będzie on również bardziej czytelny:
Tutaj umożliwiłem także używanie haseł z wiodącymi lub końcowymi znakami spacji, tymczasowo ustawiając
IFS
pusty ciąg znaków do odczytu hasłaread
.Zmieniono również logikę, aby ratować, jeśli
$ORACLE_SID
/$sid
isTest
. Pozwala to uniknąć posiadania głównej części operacyjnej skryptu wif
gałęzi.źródło
if ([ x = x ]) then (echo yes) fi
również działa.if
instrukcje z[ ... ]
... :-)Podczas pisania
sh
chceszPodczas pisania
bash
Uważaj na przestrzenie, proszę. Musi być odstęp między
[[
pierwszym operatorem.źródło