Na przykład:
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
i używając \
znaku ucieczki:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
Oczywiście robię coś głupiego.
Jak uzyskać wynik BAR * BAR
?
Cytowanie, gdy ustawienie $FOO
nie wystarczy. Musisz również zacytować odniesienie do zmiennej:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
KRÓTKA ODPOWIEDŹ
Jak powiedzieli inni - zawsze powinieneś cytować zmienne, aby zapobiec dziwnemu zachowaniu. Więc użyj echo "$ foo" in zamiast po prostu echo $ foo .
DŁUGA ODPOWIEDŹ
Myślę, że ten przykład zasługuje na dalsze wyjaśnienia, ponieważ dzieje się więcej, niż mogłoby się wydawać na pierwszy rzut oka.
Widzę, gdzie pojawia się twoje zamieszanie, ponieważ po uruchomieniu pierwszego przykładu prawdopodobnie pomyślałeś, że powłoka najwyraźniej robi:
A więc z pierwszego przykładu:
Po rozwinięciu parametrów odpowiada:
A po rozwinięciu nazwy pliku jest równoważne:
A jeśli po prostu wpiszesz
echo BAR * BAR
w wierszu poleceń, zobaczysz, że są one równoważne.Więc prawdopodobnie pomyślałeś sobie „jeśli uniknę *, mogę zapobiec rozszerzaniu nazwy pliku”
A więc z drugiego przykładu:
Po rozwinięciu parametrów powinno odpowiadać:
A po rozwinięciu nazwy pliku powinno być równoważne z:
A jeśli spróbujesz wpisać „echo BAR \ * BAR” bezpośrednio w wierszu poleceń, rzeczywiście wypisze to „BAR * BAR”, ponieważ rozwinięcie nazwy pliku jest blokowane przez znak ucieczki.
Dlaczego więc użycie $ foo nie działa?
To dlatego, że ma miejsce trzecie rozszerzenie - Quote Removal. Z ręcznego usuwania cytatów bash jest:
Więc co się dzieje, kiedy wpiszesz polecenie bezpośrednio w linii poleceń, znak ucieczki nie jest wynikiem poprzedniego interpretacji, więc BASH usuwa go przed wysłaniem do polecenia echo, ale w drugim przykładzie znak "\ *" był wynik poprzedniej interpretacji parametru, więc NIE jest usuwany. W rezultacie echo otrzymuje "\ *" i to właśnie drukuje.
Zwróć uwagę na różnicę między pierwszym przykładem - „*” nie jest uwzględniona w znakach, które zostaną usunięte przez usunięcie cytatu.
Mam nadzieję, że to ma sens. Na koniec wniosek w tym samym - wystarczy użyć cudzysłowu. Pomyślałem tylko, że wyjaśnię, dlaczego ucieczka, która logicznie powinna działać, jeśli w grę wchodzi tylko rozszerzenie parametrów i nazwy pliku, nie działa.
Aby uzyskać pełne wyjaśnienie rozszerzeń BASH, zobacz:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
źródło
Dodam trochę do tego starego wątku.
Zwykle używałbyś
Jednak nawet z taką składnią miałem problemy. Rozważmy następujący skrypt.
Te
*
muszą być przekazywane do verbatimcurl
, ale te same problemy pojawią. Powyższy przykład nie zadziała (rozwinie się do nazw plików w bieżącym katalogu) i też nie\*
. Nie możesz również cytować,$curl_opts
ponieważ zostanie to rozpoznane jako pojedyncza (nieprawidłowa) opcjacurl
.Dlatego zalecałbym użycie
bash
zmiennej,$GLOBIGNORE
aby całkowicie zapobiec rozwijaniu nazwy pliku, jeśli zostanie zastosowana do wzorca globalnego, lub użycieset -f
wbudowanej flagi.W odniesieniu do oryginalnego przykładu:
źródło
SELECT * FROM etc.
, że to jedyny sposób, który działa.źródło
źródło
Warto przyzwyczaić się do używania
printf
raczej niżecho
z linii poleceń.W tym przykładzie nie daje to większych korzyści, ale może być bardziej przydatne przy bardziej złożonych wynikach.
źródło