Posso omitir com segurança aspas no lado direito de uma atribuição local?
function foo {
local myvar=${bar}
stuff()
}
Estou interessado principalmente bash
, mas qualquer informação sobre casos de canto em outros reservatórios é bem-vinda.
shell-script
quoting
assignment
rahmu
fonte
fonte
Respostas:
Citações são necessários em
export foo="$var"
oulocal foo="$var"
(oureadonly
,typeset
,declare
e outras variáveis que declara comandos ) em:dash
sh
do NetBSD (também baseado no shell Almquist).sh
do FreeBSD 9.2 ou anterior (veja a alteração na 9.3 )yash
zsh
com versões anteriores à 5.1 emksh
oush
emulação (ou paraexport var="$(cmd)"
ondezsh
executaria a divisão de palavras de outra forma (sem globbing)).Caso contrário, a expansão da variável estaria sujeita à divisão de palavras e / ou geração de nome de arquivo, como em qualquer argumento para qualquer outro comando.
E não são necessários em:
bash
ksh
(todas as implementações)sh
do FreeBSD 9.3 ou posteriorsh
(desde 2005)zsh
Em
zsh
, split + glob nunca é feito na expansão de parâmetros, a menos que seja dentrosh
ouksh
emulado, mas split (não glob) é feito na substituição de comandos. Desde a versão 5.1,export
/local
e outros comandos de declaração se tornaram comandos de palavra-chave dupla / embutidos, como nos outros shells acima, o que significa que a citação não é necessária, mesmo emsh
/ksh
emulation e até mesmo para substituição de comando.Existem casos especiais em que é necessário citar mesmo nessas conchas, como:
Ou, de maneira mais geral, se algo restante do
=
(incluindo o=
) for citado ou o resultado de alguma expansão (comoexport 'foo'="$var"
,export foo\="$var"
ouexport foo$((n+=1))="$var"
(que$((...))
também deve ser citado na verdade) ...). Ou, em outras palavras, quando o argumento paraexport
não seria uma atribuição de variável válida se escrito sem oexport
.Se o
export
/local
nome próprio comando é citado (mesmo em parte, como"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
, ou mesmo""export a="$b"
), as aspas em torno$b
são necessários excepto AT & Tksh
emksh
.Se
export
/local
ou parte dela é resultado de alguma expansão (como emcmd=export; "$cmd" a="$b"
ou mesmoexport$(:) a="$b"
) ou em coisas comodryrun=; $dryrun export a="$b"
), então as aspas são necessárias em cada shell.No caso de
> /dev/null export a="$b"
, as cotações são necessárias empdksh
e alguns de seus derivados.Pois
command export a="$b"
, as aspas são necessárias em todos os shell, masmksh
eksh93
(com as mesmas ressalvas sobrecommand
eexport
não sendo o resultado de alguma expansão).Eles não são necessários em nenhum shell quando gravados:
(essa sintaxe também é compatível com o shell Bourne, mas nas versões recentes do
zsh
, funcionando apenas quando emsh
/ksh
emulação).(observe que
var=value local var
não deve ser usado, pois o comportamento varia entre as conchas).Observe também que o uso
export
com uma atribuição também significa que o status de saída decmd
inexport var="$(cmd)"
é perdido. Fazê-lo comoexport var; var=$(cmd)
não tem esse problema.Também tenha cuidado com este caso especial com
bash
:Meu conselho seria sempre citar.
fonte
zsh
aspas são necessáriaslocal foo="$(cmd)"
porque a divisão de palavras (mas não a geração do nome do arquivo) é executada para substituições de comandos semKSH_TYPESET
aspas (mas não para expansões de parâmetros sem aspas ), a menos que esteja ativada, nesse caso as aspas não são necessárias. Faz sentido? Não? Sempre cite tudo, a menos que você saiba exatamente o que está fazendo.Geralmente cito qualquer uso de variáveis em que possa haver caracteres como espaços em branco. Caso contrário, você terá problemas como este:
O uso da variável em uma atribuição não parece precisar de aspas, mas quando você a usar, como no exemplo,
printf
precisará citá-la:NOTA: Lembre - se de que a variável
$IFS
é o que governa quais são os caracteres separadores.Exemplo
Com a depuração ativada no Bash, podemos ver o que está acontecendo nos bastidores.
No exposto acima, podemos ver que a variável
$bar
foi transferida para$myvar
mas, quando fomos usar$myvar
, tivemos que conhecer o conteúdo de$myvar
quando fomos usá-la.fonte
bash
eksh
emlocal
/typeset
... builtins especiais).