Podaj zmienną w instrukcji „if” skryptu powłoki

9

na przykład

if [ "$FOO" = "true" ]; then

vs

if [ $FOO = "true" ]; then

Czym się różni? Wydaje się, że oba te stwierdzenia również działają.

Ryan
źródło
W Bash używaj podwójnych nawiasów kwadratowych i nie potrzebujesz cudzysłowów, a zyskujesz dodatkowe korzyści .
Wstrzymano do odwołania.
@DennisWilliamson Niezupełnie, potrzebujesz cytatów po prawej stronie (nie) operatorów równości i dopasowywania wzorców.
Gilles „SO- przestań być zły”
@Gilles: Czasami nie. Na dosłownych ciągów zawierających spacje lub za dosłowne ciągi lub zmiennych, które zawierają znaki glob, że chcesz być brane dosłownie , po prawej stronie musi być podane: a='foo bar'; [[ $a == "foo bar" ]]. Jednak zmienna, która nie zawiera znaków glob nie musi być: [[ $a == $a ]]. Rozwijanie wyrazów nie jest wykonywane w nawiasach kwadratowych. I dla regex dopasowywania, wzór na prawej stronie nie mogą być notowane lub będzie ona traktowana jako dosłowne wyrażenie: [[ $a =~ .*oo.*r ]](wzór powinien być w zmiennej un cytowany jednak zamiast ...
. Wstrzymane do odwołania
włączenia dosłownie jak tutaj). Dla glob stylu dopasowywania wzorców, znaki glob nie musi być cytowany, czy dosłowne lub w zmiennej: [[ $a == foo* ]]. Czy możesz podać jakieś dodatkowe przykłady wymogu cytowania oprócz mojego przykładu literału?
Wstrzymano do odwołania.

Odpowiedzi:

6

Jeśli wartością $FOOjest pojedyncze słowo, które nie zawiera znaku wieloznacznego \[*?, oba są identyczne.

Jeśli $FOOjest nieprzypisane, puste lub zawiera więcej niż jedno słowo (tzn. Zawiera spacje lub $IFS), wówczas wersja bez cudzysłowu jest błędem składni. Jeśli zdarzy się, że jest to właściwa sekwencja słów (np. 0 -eq 0 -o false), Wynik może być dowolny. Dlatego dobrą praktyką jest zawsze cytowanie zmiennych w skryptach powłoki.

Nawiasem mówiąc, "true"nie trzeba cytować.

200_sukces
źródło
3

Aby zilustrować problemy, które może powodować, oto kilka przykładów.

Powiedzmy, że mamy dwie zmienne:

FOO="some value"
BAR="some value"

Teraz mamy dwie zmienne posiadające dokładnie ten sam ciąg / wartość. Jeśli zrobiliśmy kilka instrukcji if w celu przetestowania wyniku, w twoim przypadku:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

W tym momencie dostaniesz bash: [: too many arguments. Nienotowany $ FOO ma teraz trzy wartości, a mianowicie '[ , some , value'. [słowo kluczowe test nie wie, co wykonać, ponieważ oczekuje, że pierwszym lub drugim argumentem będzie operator.

Kiedy cytujemy „$ FOO”, wyraźnie mówimy ifo sprawdzeniu właściwych wartości, w których nie dochodzi do podziału słów.

Inny przykład:

my_file="A random file.txt"
  • robienie rm $my_fileoznacza usuwanie „losowego” pliku.txt, co czyni go trzema plikami.
  • zrobienie rm "$my_file"usunie „Losowy plik.txt”, który utworzy jeden plik.

Mam nadzieję, że nie pomyliłem cię z tymi przykładami.

Valentin Bajrami
źródło
0

W tym konkretnym przypadku nie ma różnicy.

Jeśli jednak $FOOzawiera spację lub znaki specjalne, będziesz mieć problem.

W takim "$FOO"przypadku użyje zmiennej ogółem, aby dopasowanie dopasowało Cię do problemu z przestrzenią.

Jeśli jednak użyjesz $FOOi istnieje specjalny przypadek, wpłynie to na instrukcję if.

mdpc
źródło