¿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
,declare
y otras variables que se declara comandos ) en:dash
sh
de NetBSD (también basado en el shell Almquist).sh
de FreeBSD 9.2 o anterior (ver el cambio en 9.3 )yash
zsh
con versiones anteriores a 5.1 enksh
osh
emulación (o paraexport var="$(cmd)"
dóndezsh
se 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:
bash
ksh
(todas las implementaciones)sh
de FreeBSD 9.3 o más recientesh
(desde 2005)zsh
En
zsh
, split + glob nunca se realiza tras la expansión de parámetros, a menos que sea ensh
oksh
emulación, pero split (no glob) se realiza tras la sustitución del comando. Desde la versión 5.1,export
/local
y 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
/ksh
emulació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 queexport
no sería una asignación de variables válidas si son escritos sin elexport
.Si el
export
/local
nombre 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$b
son necesarias excepto en AT & Tksh
ymksh
.Si
export
/local
o 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 enpdksh
y algunos de sus derivados.Para
command export a="$b"
, las comillas son necesarias en cada shell peromksh
yksh93
(con las mismas advertencias sobrecommand
yexport
no 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
/ksh
emulación).(Tenga en cuenta que
var=value local var
no debe ser utilizado como el comportamiento varía a través de conchas).También tenga en cuenta que el uso
export
de una asignación también significa que el estado de salidacmd
deexport 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
zsh
comillas 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_TYPESET
esté 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
printf
necesitará citada allí:NOTA: Recuerde que la variable
$IFS
es 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
$bar
se transmitió bien,$myvar
pero luego, cuando la usamos$myvar
, teníamos que ser conscientes del contenido de$myvar
cuándo la usamos.fuente
bash
andksh
inlocal
/typeset
... builtins especiales).