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.
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.
Odpowiedzi:
Cytaty są potrzebne export foo="$var"lub local foo="$var"(i readonly, typeset, declarea pozostałe zmienne deklarowania poleceń ) z:
dashshNetBSD (również w oparciu o Almquist Shell).shFreeBSD 9.2 lub starsza (patrz zmiana w 9.3 )yashzshz wersjami wcześniejszymi niż 5.1 kshlub shemulującymi (lub dla export var="$(cmd)"których w zshinnym 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:
bashksh (wszystkie wdrożenia)shFreeBSD 9.3 lub nowszejsh(od 2005)zshW zsh, split + glob nigdy nie jest wykonywane po rozszerzeniu parametru, chyba że w shlub kshemulacji, ale split (nie glob) jest wykonywany po zastąpieniu polecenia. Od wersji 5.1, export/ locali inne polecenia deklaracji stały podwójny kluczowe / wbudowane komendy jak w innych skorup powyżej, co oznacza, cytując nie jest konieczne, nawet w sh/ kshemulacji, a nawet do zastąpienia poleceń.
Istnieją specjalne przypadki, w których cytowanie jest potrzebne nawet w tych powłokach, jak na przykład:
a="b=some value"
export "$a"
Lub bardziej ogólnie, jeśli cokolwiek zostało z =(w tym =) jest cytowane lub jest wynikiem jakiegoś rozszerzenia (jak export 'foo'="$var", export foo\="$var"lub export foo$((n+=1))="$var"(które $((...))powinno być faktycznie cytowane) ...). Innymi słowy, gdy argument argumentu exportnie byłby prawidłowym przypisaniem zmiennej, gdyby został napisany bez export.
Jeśli export/ localsama 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ół $bpotrzebne są wyjątkiem AT & T kshi mksh.
Jeśli export/ locallub jakaś jego część jest wynikiem jakiegoś rozszerzenia (jak w cmd=export; "$cmd" a="$b"lub nawet export$(:) a="$b") lub w rzeczach takich jak dryrun=; $dryrun export a="$b"), wówczas cudzysłowy są potrzebne w każdej powłoce.
W przypadku > /dev/null export a="$b", potrzebne są notowania pdkshi niektóre z jego pochodnych.
Ponieważ command export a="$b"cytaty są potrzebne w każdej powłoce, ale mkshi ksh93(z tymi samymi zastrzeżeniami commandi exportnie będącymi wynikiem niektórych rozszerzeń).
Po napisaniu nie są potrzebne w żadnej powłoce:
foo=$var export foo
(ta składnia jest również kompatybilna z powłoką Bourne'a, ale w najnowszych wersjach zshdziała tylko w trybie sh/ kshemulacji).
(należy pamiętać, że var=value local varnie 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 exportz przypisaniem oznacza również utratę statusu wyjścia dla cmdin export var="$(cmd)". Robienie tego, ponieważ export var; var=$(cmd)nie ma tego problemu.
Uważaj również na ten specjalny przypadek z bash:
$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b
Radzę zawsze cytować.
zshcudzysł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 że KSH_TYPESETjest 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:
#!/bin/bash
bar="hi bye"
function foo {
local myvar=${bar}
printf "%s\n" $myvar
printf "%s\n" "$myvar"
}
foo
Użycie zmiennej w przydziale nie wydaje się wymagać cudzysłowów, ale kiedy idziesz do jej użycia, tak jak w printftekście, musisz ją tam zacytować:
printf "%s\n" "$myvar"
UWAGA: Pamiętaj, że zmienna $IFSdecyduje o tym, jakie są znaki separatora.
IFS The Internal Field Separator that is used for word splitting after
expansion and to split lines into words with the read builtin command.
The default value is ``<space><tab><newline>''.
Po włączeniu debugowania w Bash możemy zobaczyć, co dzieje się za kulisami.
$ bash -x cmd.bash
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye
Powyżej widać, że zmienna $barzostała dobrze przekazana, $myvarale kiedy poszliśmy z niej korzystać $myvar, musieliśmy być poznawcami zawartości, $myvarkiedy z niej skorzystaliśmy.
bashoraz kshw local/ typeset... Specjalne builtins).