Jakie jest znaczenie pojedynczych i podwójnych cudzysłowów w zmiennych środowiskowych?

19

W moim pliku .profile zdefiniowałem niektóre zmienne środowiskowe, takie jak:

MY_HOME="/home/my_user"

ale zmienna nie wydaje się oceniać, chyba że usunę cudzysłowy i ponownie źródła pliku. Uważam, że cytaty są konieczne, jeśli pojawią się spacje, a pojedyncze cudzysłowy są używane, jeśli znaki ucieczki nie są pożądane. Czy ktoś może wyjaśnić znaczenie pojedynczych i podwójnych cudzysłowów w definicjach zmiennych? Co powiesz na przednie i tylne tyknięcia?

2NinerRomeo
źródło

Odpowiedzi:

23

Myślę, że masz wątpliwości co do terminologii.

„Zmienna środowiskowa” jest jedynie zmienną powłoki, którą odziedziczą wszelkie procesy potomne.

W tym przykładzie robisz tworzenie zmiennej powłoki. Nie ma go w środowisku, dopóki go nie wyeksportujesz:

MY_HOME="/home/my_user"
export MY_HOME

umieszcza zmienną o nazwie „MY_HOME” w prawie wszystkich powłokach (z wyjątkiem csh, tcsh).

W tym konkretnym przypadku podwójne cudzysłowy są zbędne. Nie mają wpływu. Podwójne cudzysłowy grupują podciągi, ale zezwalają na dowolną powłokę, której użyjesz do podstawienia zmiennych. Pojedyncze cudzysłowy grupuje podciągi i zapobiega podstawieniu. Ponieważ w przykładowym zadaniu nie ma żadnych zmiennych, podwójne cudzysłowy mogły pojawić się jako pojedyncze cudzysłowy.

V='some substrings grouped together'  # assignment
X="Put $V to make a longer string"    # substitution and then assignment
Y=`date`                              # run command, assign its output
Z='Put $V to make a longer string'    # no substition, simple assignment

Nic nie jest w środowisku, dopóki go nie wyeksportujesz.

Bruce Ediger
źródło
18

Zmienne powłoki a zmienne środowiskowe

MY_HOME="/home/my_user"ustawia zmienną powłoki o nazwie MY_HOME. Powłoki są językami programowania i mają zmienne (zwane również parametrami). Po tym przypisaniu możesz użyć wartości zmiennej, np echo "$MY_HOME". Za pomocą .

Zmienne powłoki są wewnętrzną koncepcją powłoki. Kiedy ta instancja powłoki kończy się, MY_HOMEzostaje zapomniana. Każdy program wie i przekazuje swoim dzieciom zmienne środowiskowe .

Wewnątrz powłoki zmienne środowiskowe i zmienne powłoki działają w bardzo podobny sposób. W rzeczywistości wszystkie zmienne środowiskowe, które powłoka dziedziczy od swojego rodzica, stają się zmiennymi powłoki. I odwrotnie, zmienna powłoki zdefiniowana w skrypcie powłoki stanie się zmienną środowiskową, jeśli zostanie wyeksportowana .

export MY_HOME="/home/my_user"

Więcej szczegółów możesz pominąć przy pierwszym czytaniu

Powodem, dla którego zmienne powłoki nie stają się automatycznie zmiennymi środowiskowymi, jest częściowo to, że skrypt może przypadkowo użyć nazwy zmiennej, która ma znaczenie dla uruchamianego programu, a częściowo tylko historycznej.

Niektóre bardzo stare powłoki wymagały exportużycia za każdym razem, gdy zmieniasz nazwę zmiennej, ale wszystkie nowoczesne powłoki śledzą przypisania zmiennych środowiskowych, dzięki czemu echo następującego fragmentu kodu bar:

myvar=foo
export myvar
myvar=bar
env | grep '^myvar='

Ponadto niektóre bardzo stare powłoki wymagały osobnych poleceń dla myvar=fooi export myvar, ale wszystkie współczesne powłoki rozumieją export myvar=foo.

Możesz uruchomić, set -aaby wszystkie przypisania zmiennych powłoki automatycznie eksportowały zmienną, co myvar=foojest równoważne z tym, export myvar=fooże najpierw uruchomiłeś ją set -aw tej powłoce.

Przy cytowaniu

Cytowanie jest w większości ortogonalne. Jeśli wartość, którą przypisujesz zmiennej, nie zawiera żadnych znaków specjalnych dla powłoki, nie potrzebujesz cudzysłowów. Jeśli są znaki specjalne, musisz je chronić za pomocą pojedynczych cudzysłowów lub podwójnych cudzysłowów lub odwrotnych ukośników lub ich kombinacji. Dotyczy to zarówno zwykłej myvar=valueskładni, jak i exportnarzędzia.

Istnieje jedna różnica między składnią przypisania a exportskładnią. Powłoka rozszerza dalej wyniki podstawień zmiennych $foo, dokonując podziału pól (słów) i rozwijania nazw ścieżek (globbing) . Oznacza to, że jeśli wartością myvarjest hello ​ *, to echo $myvarwypisuje, helloa następnie pojedynczą spację, a następnie listę plików w bieżącym katalogu. To prawie nigdy pożądane, stąd ogólna zasada, aby zawsze używać cudzysłowie zmiana zmiennych (chyba że wiesz, że potrzebują Państwo PathName ekspansję lub podziału dziedzinie): echo "$myvar". W przypadku prostego przypisania othervar=$myvarw rzeczywistości niezawodnie kopiuje wartość myvardoothervar, ponieważ globowanie i dzielenie słów są blokowane w przypisaniach (ponieważ tworzą wiele słów, ale oczekuje się pojedynczego słowa). To zwolnienie nie ma jednak zastosowania export. Więc jeśli chcesz zapamiętać prostą regułę, zawsze używaj podwójnych cudzysłowów wokół podstawień zmiennych.

Gilles „SO- przestań być zły”
źródło
Czy możesz wyjaśnić: „Cytowanie jest głównie ortogonalne”. w sekcji „O cytowaniu”? W tym zdaniu nie rozumiem znaczenia ortogonalnego .
DK Bose
1
@DKBose Oznacza to, że zmienne środowiskowe vs zmienne powłoki z jednej strony, a cytowanie z drugiej strony, to dwa osobne problemy, które mają niewiele wspólnego ze sobą. Wikisłownik znaczenie 4 i 5.
Gilles 'SO- przestań być zły'