Niekoniecznie chcę odpowiedzi, ale jeśli ktoś mógłby wskazać mi literaturę lub przykłady. Chciałbym to rozgryźć.
Po uruchomieniu skryptu pojawia się błąd:
Błąd składni w pobliżu nieoczekiwanego tokena
fi
Wydedukowałem, że mój problem tkwi w moim oświadczeniu, komentując if
moje if
oświadczenia i dodając, echo "$NAME"
który wyświetla nazwy w /etc/
.
Kiedy wprowadzam zmiany, usuwam #
z if
i fi
dodawam #
do wc -c "$NAME"
, pojawia się błąd składni wymieniony powyżej. Dodałem ;
między ]
tym. Przeszedłem również then
do następnego wiersza bez rozdzielczości.
#!/bin/bash
for NAME in /etc/*
do
if [ -r "$NAME" -af "$NAME" ] then
wc -c "$NAME"
fi
done
-af
ma zrobić?-a
jest zbędny, ponieważ warunek jest już uwzględniony-f
. --- W każdym razie wiele warunków w obrębie[ ]
(to polecenie jest również dostępne jakotest
) należy połączyć za pomocą operatorów logicznych, takich jak-a
(i) lub-o
(lub), ale jak sugerowano w odpowiedzi poniżej, lepiej jest używać wielu[ ]
(test
) poleceń i łączyć za pomocą operatorów powłoki takich jak&&
lub||
.Odpowiedzi:
Słowa kluczowe jak
if
,then
,else
,fi
,for
,case
i tak dalej musi być w miejscu, gdzie powłoka oczekuje nazwę polecenia. W przeciwnym razie są traktowane jak zwykłe słowa. Na przykład,po prostu drukuje
if
, nie uruchamia instrukcji warunkowej.Tak więc w kolejce
słowo
then
jest argumentem polecenia[
(na które narzekałby, gdyby kiedykolwiek mógł uruchomić). Powłoka wciąż szukathen
i znajdujefi
pozycję dowodzenia. Ponieważ jest cośif
, co wciąż go szukathen
,fi
jest to nieoczekiwane, wystąpił błąd składniowy.Musisz wcześniej wstawić terminator poleceń
then
, aby został rozpoznany jako słowo kluczowe. Najczęstszym terminatorem poleceń jest podział linii, ale wcześniejthen
często stosuje się średnik (który ma dokładnie takie samo znaczenie jak podział linii).lub
Po naprawieniu
[
pojawi się kolejny błąd polecenia, ponieważ nie rozumie-af
. Prawdopodobnie miałeś na myśliChociaż polecenia testowe wyglądają jak opcje, nie można ich w taki sposób spakować. Są operatorami
[
polecenia i muszą być osobnymi słowami (tak jak[
i]
).Nawiasem mówiąc, chociaż
[ -r "$NAME" -a -f "$NAME" ]
działa, polecam albo pisaćlub
Najlepiej jest zachować
[ … ]
warunki warunkowe, ponieważ[
polecenie nie może łatwo odróżnić operatorów od operandu. Jeśli$NAME
wygląda jak operator i pojawia się w pozycji, w której operator jest poprawny, można go przeanalizować jako operator. Nie zdarzy się to w prostych przypadkach przedstawionych w tej odpowiedzi, ale bardziej złożone przypadki mogą być ryzykowne. Pisanie tego z osobnymi wywołaniami[
i używanie operatorów logicznych powłoki pozwala uniknąć tego problemu.Druga składnia wykorzystuje
[[ … ]]
konstrukcję warunkową, która istnieje w bash (i ksh i zsh, ale nie zwykły sh). Ta konstrukcja jest specjalna składnia, natomiast[
jest analizowany jak inne polecenia, więc można używać rzeczy jak&&
wewnątrz i nie trzeba do zmiennych cytując wyjątkiem argumenty niektórych operatorów strunowych (=
,==
,!=
,=~
) (patrz Kiedy jest to konieczne dwukrotne cytowanie ? po szczegóły).źródło
if [[ 1 ]] then [[ 2 ]] fi
działa w ksh, pdksh i zsh.if(:)then(:)fi
działa we wszystkich powłokach.Zobacz, co się zmieniło w następujący sposób
Jeśli chcesz usunąć wszystkie polecenia w bloku if, musisz przynajmniej dodać dwukropek
lub wersja jednoliniowa
if [ -r "$NAME" -a -f "$NAME" ]; then :; fi
źródło
Inni już zauważyli, ale jeśli szukasz oficjalnej referencji, to RTM
Tęsknisz za
;
Składnia
list
jest opisana wman test
źródło