¿Puedo omitir con seguridad las cotizaciones en el lado derecho de una asignación local?
function foo {
local myvar=${bar}
stuff()
}
Estoy interesado principalmente bash, pero cualquier información sobre casos de esquina en otros shells es bienvenida.
shell-script
quoting
assignment
rahmu
fuente
fuente

Respuestas:
Se necesitan Cotizaciones en
export foo="$var"olocal foo="$var"(oreadonly,typeset,declarey otras variables que se declara comandos ) en:dashshde NetBSD (también basado en el shell Almquist).shde FreeBSD 9.2 o anterior (ver el cambio en 9.3 )yashzshcon versiones anteriores a 5.1 enkshoshemulación (o paraexport var="$(cmd)"dóndezshse dividiría la palabra de otra manera (no globular)).De lo contrario, la expansión de la variable estaría sujeta a la división de palabras y / o generación de nombre de archivo como en cualquier argumento a cualquier otro comando.
Y no son necesarios en:
bashksh(todas las implementaciones)shde FreeBSD 9.3 o más recientesh(desde 2005)zshEn
zsh, split + glob nunca se realiza tras la expansión de parámetros, a menos que sea enshokshemulación, pero split (no glob) se realiza tras la sustitución del comando. Desde la versión 5.1,export/localy otros comandos de declaración se han convertido en comandos duales de palabras clave / incorporados como en los otros shells anteriores, lo que significa que no es necesario citar, incluso ensh/kshemulación e incluso para la sustitución de comandos.Hay casos especiales en los que es necesario citar incluso en esos depósitos, como:
O más en general, en todo caso queda de la
=(incluyendo el=) es citado o el resultado de una cierta expansión (comoexport 'foo'="$var",export foo\="$var"oexport foo$((n+=1))="$var"(que$((...))también debe citarse en realidad) ...). O en otras palabras, cuando el argumento de queexportno sería una asignación de variables válidas si son escritos sin elexport.Si el
export/localnombre del comando en sí es citado (aunque sea en parte, como"export" a="$b",'ex'port a="$b",\export a="$b", o incluso""export a="$b"), las comillas$bson necesarias excepto en AT & Tkshymksh.Si
export/localo alguna parte es el resultado de una expansión (como encmd=export; "$cmd" a="$b"o inclusoexport$(:) a="$b") o en cosas comodryrun=; $dryrun export a="$b"), entonces las comillas son necesarias en cada shell.En el caso de
> /dev/null export a="$b", son necesarias las comillas enpdkshy algunos de sus derivados.Para
command export a="$b", las comillas son necesarias en cada shell peromkshyksh93(con las mismas advertencias sobrecommandyexportno ser el resultado de alguna expansión).Ellos no son necesarios en cualquier shell cuando se escribe:
(que la sintaxis ser también compatible con el shell Bourne pero en versiones recientes de
zsh, trabajar sólo cuando ensh/kshemulación).(Tenga en cuenta que
var=value local varno debe ser utilizado como el comportamiento varía a través de conchas).También tenga en cuenta que el uso
exportde una asignación también significa que el estado de salidacmddeexport var="$(cmd)"se pierde. Hacerlo comoexport var; var=$(cmd)no tiene ese problema.También tenga cuidado con este caso especial con
bash:Mi consejo sería citar siempre.
fuente
zshcomillas son necesariaslocal foo="$(cmd)"porque la división de palabras (pero no la generación de nombre de archivo) se realiza para sustituciones de comandos sin comillas (pero no para expansiones de parámetros sin comillas), a menos queKSH_TYPESETesté habilitado, en cuyo caso no se necesitan comillas . ¿Tener sentido? ¿No? Luego, siempre cita todo a menos que sepas exactamente lo que estás haciendo.En general, cito cualquier uso de variables donde pueda haber caracteres como espacios en blanco. De lo contrario, tendrás problemas como este:
El uso de la variable en una asignación no parece necesitar las comillas, pero cuando vaya a usarla como en la
printfnecesitará citada allí:NOTA: Recuerde que la variable
$IFSes lo que gobierna cuáles son los caracteres separadores.Ejemplo
Con la depuración habilitada en Bash podemos ver lo que sucede detrás de escena.
En lo anterior, podemos ver que la variable
$barse transmitió bien,$myvarpero luego, cuando la usamos$myvar, teníamos que ser conscientes del contenido de$myvarcuándo la usamos.fuente
bashandkshinlocal/typeset... builtins especiales).