Czy mogę bezpiecznie pominąć cytaty po prawej stronie zadania lokalnego?
function foo {
local myvar=${bar}
stuff()
}
Interesuje mnie głównie bash
, ale mile widziane są wszelkie informacje na temat narożnych skrzynek w innych powłokach.
shell-script
quoting
assignment
rahmu
źródło
źródło
Odpowiedzi:
Cytaty są potrzebne
export foo="$var"
lublocal foo="$var"
(ireadonly
,typeset
,declare
a pozostałe zmienne deklarowania poleceń ) z:dash
sh
NetBSD (również w oparciu o Almquist Shell).sh
FreeBSD 9.2 lub starsza (patrz zmiana w 9.3 )yash
zsh
z wersjami wcześniejszymi niż 5.1ksh
lubsh
emulującymi (lub dlaexport var="$(cmd)"
których wzsh
innym przypadku wykonywałby dzielenie słów (bez globowania)).W przeciwnym razie interpretacja zmiennych podlegałaby podziałowi słów i / lub generowaniu nazw plików, jak w każdym argumencie do dowolnego innego polecenia.
I nie są potrzebne w:
bash
ksh
(wszystkie wdrożenia)sh
FreeBSD 9.3 lub nowszejsh
(od 2005)zsh
W
zsh
, split + glob nigdy nie jest wykonywane po rozszerzeniu parametru, chyba że wsh
lubksh
emulacji, ale split (nie glob) jest wykonywany po zastąpieniu polecenia. Od wersji 5.1,export
/local
i inne polecenia deklaracji stały podwójny kluczowe / wbudowane komendy jak w innych skorup powyżej, co oznacza, cytując nie jest konieczne, nawet wsh
/ksh
emulacji, a nawet do zastąpienia poleceń.Istnieją specjalne przypadki, w których cytowanie jest potrzebne nawet w tych powłokach, jak na przykład:
Lub bardziej ogólnie, jeśli cokolwiek zostało z
=
(w tym=
) jest cytowane lub jest wynikiem jakiegoś rozszerzenia (jakexport 'foo'="$var"
,export foo\="$var"
lubexport foo$((n+=1))="$var"
(które$((...))
powinno być faktycznie cytowane) ...). Innymi słowy, gdy argument argumentuexport
nie byłby prawidłowym przypisaniem zmiennej, gdyby został napisany bezexport
.Jeśli
export
/local
sama nazwa polecenia jest cytowany (nawet w części, takich jak"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
, lub nawet""export a="$b"
), cytaty wokół$b
potrzebne są wyjątkiem AT & Tksh
imksh
.Jeśli
export
/local
lub jakaś jego część jest wynikiem jakiegoś rozszerzenia (jak wcmd=export; "$cmd" a="$b"
lub nawetexport$(:) a="$b"
) lub w rzeczach takich jakdryrun=; $dryrun export a="$b"
), wówczas cudzysłowy są potrzebne w każdej powłoce.W przypadku
> /dev/null export a="$b"
, potrzebne są notowaniapdksh
i niektóre z jego pochodnych.Ponieważ
command export a="$b"
cytaty są potrzebne w każdej powłoce, alemksh
iksh93
(z tymi samymi zastrzeżeniamicommand
iexport
nie będącymi wynikiem niektórych rozszerzeń).Po napisaniu nie są potrzebne w żadnej powłoce:
(ta składnia jest również kompatybilna z powłoką Bourne'a, ale w najnowszych wersjach
zsh
działa tylko w trybiesh
/ksh
emulacji).(należy pamiętać, że
var=value local var
nie należy tego używać, ponieważ zachowanie różni się w zależności od powłoki).Należy również pamiętać, że używanie
export
z przypisaniem oznacza również utratę statusu wyjścia dlacmd
inexport var="$(cmd)"
. Robienie tego, ponieważexport var; var=$(cmd)
nie ma tego problemu.Uważaj również na ten specjalny przypadek z
bash
:Radzę zawsze cytować.
źródło
zsh
cudzysłowach są potrzebne,local foo="$(cmd)"
ponieważ dzielenie słów (ale nie generowanie nazw plików) jest wykonywane dla niecytowanych podstawień poleceń (ale nie dla niecytowanych rozszerzeń parametrów), chyba żeKSH_TYPESET
jest włączone, w którym to przypadku cudzysłowy nie są potrzebne. Ma sens? Nie? Następnie zawsze cytuj wszystko, chyba że wiesz dokładnie, co robisz.Zazwyczaj cytuję użycie zmiennych, w których mogą występować znaki, takie jak białe znaki. W przeciwnym razie wystąpią takie problemy:
Użycie zmiennej w przydziale nie wydaje się wymagać cudzysłowów, ale kiedy idziesz do jej użycia, tak jak w
printf
tekście, musisz ją tam zacytować:UWAGA: Pamiętaj, że zmienna
$IFS
decyduje o tym, jakie są znaki separatora.Przykład
Po włączeniu debugowania w Bash możemy zobaczyć, co dzieje się za kulisami.
Powyżej widać, że zmienna
$bar
została dobrze przekazana,$myvar
ale kiedy poszliśmy z niej korzystać$myvar
, musieliśmy być poznawcami zawartości,$myvar
kiedy z niej skorzystaliśmy.źródło
bash
orazksh
wlocal
/typeset
... Specjalne builtins).