Powiedzmy, że mamy 2 liczby całkowite w skrypcie bash:
value1=5
value2=3
Dlaczego więc musimy używać podwójnych cudzysłowów w przypadku testu? Na przykład:
if [[ "$value1" -eq "$value2" ]]
Dlaczego nie skorzystać z poniższych?
if [[ $value1 -eq $value2 ]]
Dla mnie podwójne cytaty nie mają żadnego sensu.
5
i3
jest łatwość konserwacji. Wartości mogą ulec zmianie później, a powstałe błędy mogą nie być oczywiste.[[ ]]
, tylko dla[ ]
.[[ ]]
których również wymuszają operandy-eq
na liczby całkowite.Odpowiedzi:
Podział słów.
Ten przykład jest bardzo nieprawdopodobny, ale możliwy , więc jeśli chcesz kodować defensywnie, zakryj swoje utwory cytatami:
OK, jak dotąd wszystko dobrze. Wrzućmy klucz do kół zębatych:
Ups
Ahh
źródło
[[ ]]
konstrukcji bash .[ $value1 -eq $value2 ]
z pustymvalue1
byłoby'[' -eq 3 ']'
bez''
po lewej stronie.Tak naprawdę nie potrzebujesz tutaj cytatów. Jest to jeden z nielicznych przypadków, w których można bezpiecznie używać zmiennej niecytowanej. Możesz to potwierdzić za pomocą
set -x
:Jak widać powyżej, cytowane i niecytowane wersje testu są rozwiązywane dokładnie tak samo przez bash. To samo powinno być prawdą
zsh
i, jak sądzę, każdą inną powłoką, która obsługuje[[ ]]
operatora.Pamiętaj, że nie jest tak w przypadku bardziej przenośnych
[ ]
:[ ]
Konstrukt, w przeciwieństwie do[[ ]]
jednego, nie wymaga cytowania.Kilka przydatnych linków, aby dowiedzieć się więcej o tym, kiedy i dlaczego wymagane jest cytowanie:
źródło
declare -i var1=
jest0
oceniany.-eq
jest to porównanie arytmetyczne , więc możesz nawet pominąć$
(w[[ .. ]]
) i pisać[[ a -eq b ]]
. Przy porównywaniu ciągów potrzebujesz$
oczywiście, więc[[ $a = $b ]]
var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match
. Jeśli chcesz używać znaków globu bez działania jako glob w kontekście globowania (takim jak[[ ]]
), musisz zacytować, tak.((...))
lub$((...)
. Wygląda na to, że działa, ale (stary zrzędliwy mężczyzna, włącz) Nie podoba mi się to.-eq
i przyjaciele wewnątrz[[ ]]
są również kontekstami arytmetycznymi. :) (Powiązane: Automatyczne rozszerzanie zmiennych wewnątrz polecenia bash [[]] )Mimo że podwójne cudzysłowy nie są konieczne, powody ich zastosowania to:
value1
ivalue2
są zmienne i możesz nie wiedzieć, co one zawierają. W przeciwnym razie równie dobrze możesz zapytać: „Po co zawracać sobie głowę zmiennymi zamiast sprawdzaćif [[ 5 -eq 3 ]]
? Albo pójść dalej, poif
co w ogóle zawracać sobie głowę, skoro już wiesz, że 5 nie jest równe 3? Często lepiej jest być defensywnym. (To prawda dzielenie słów nie nastąpi[[
, ale przypadki, w których dzielenie słów się nie zdarza, są rzadkie. Ponownie zobacz pierwszy punkt).źródło
Nie bezpośrednio związane z twoim pytaniem, ale używam
kiedy porównuję liczby, ale tam też nie musicie używać cudzysłowów.
źródło
if (( value1 == value2 )); then
. W kontekście arytmetycznym nawet nie potrzebujesz$
. To pytanie wydaje się jednak koncentrować na zmiennych używanych w[[ ... ]]
testach.Masz absolutną rację!
Cytowanie w podwójnych nawiasach kwadratowych nie ma żadnego sensu, przynajmniej w tym przypadku.
Ale ponieważ codziennie używam podwójnych cudzysłowów - szczególnie w przypadku wyrażeń w nawiasach kwadratowych, przekazywania argumentów do funkcji i skryptów, a także czasami przypisywania zmiennych (co jest całkowicie bezużyteczne w przypadku prostych delarkacji) - wydaje mi się, że niektórzy ludzie, przynajmniej tak robię, instynktownie pisz podwójne cudzysłowy wokół zmiennych .
Korzyść z konsekwentnego i zrozumiałego wykonywania podwójnych cudzysłowów - ale tylko wtedy, gdy ma to sens - polega na tym, że nowicjusze w bash mogą nauczyć się pisać bardziej stabilne skrypty . Podkreśla to również fakt, że sztuka przetwarzania danych za pomocą bash polega bardziej na oddzielaniu strumieni danych (w tym zmiennych) za pomocą separatorów pól i przepuszczaniu ich przez filtry . Gdy tylko oddzielisz fragmenty danych od strumienia, trzymaj je razem z podwójnymi cudzysłowami!
Kolejną korzyścią może być lepsza czytelność skryptów bash z podwójnie napisanymi ciągami w edytorze podświetlania kodu .
źródło