puedo escribir
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
El resultado final para mí parece casi igual. ¿Por qué debería escribir uno u otro? ¿Alguno de estos no es portátil / POSIX?
fuente
puedo escribir
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
El resultado final para mí parece casi igual. ¿Por qué debería escribir uno u otro? ¿Alguno de estos no es portátil / POSIX?
VAR=$VAR1
es una versión simplificada de VAR=${VAR1}
. Hay cosas que el segundo puede hacer que el primero no puede, por ejemplo, hacer referencia a un índice de matriz (no portátil) o eliminar una subcadena (POSIX-portátil). Consulte la sección Más sobre variables de la Guía Bash para principiantes y Expansión de parámetros en la especificación POSIX.
Usar comillas alrededor de una variable como en rm -- "$VAR1"
o rm -- "${VAR}"
es una buena idea. Esto hace que el contenido de la variable sea una unidad atómica. Si el valor de la variable contiene espacios en blanco (bueno, caracteres en la $IFS
variable especial, espacios en blanco por defecto) o caracteres globales y no lo cita, entonces cada palabra se considera para la generación de nombre de archivo (globalización) cuya expansión genera tantos argumentos para lo que sea que estas haciendo.
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
Sobre portabilidad: de acuerdo con POSIX.1-2008 sección 2.6.2 , las llaves son opcionales.
var1=$var
expansión da un error?export VAR=$VAR1
. En cuanto a las llaves, son opcionales (verifique el cuarto párrafo de la sección que citó; este es el caso en todos los shells pre-POSIX y POSIX).${VAR}
y$VAR
son exactamente equivalentes Para una expansión de variable simple, la única razón para usar${VAR}
es cuando el análisis de otra manera tomaría demasiados caracteres en el nombre de la variable, como en${VAR1}_$VAR2
(que sin llaves sería equivalente a${VAR1_}$VAR2
). Expansiones más adornados (${VAR:=default}
,${VAR#prefix}
, ...) requieren apoyos.En una asignación variable, la división del campo (es decir, la división en el espacio en blanco en el valor) y la expansión del nombre de ruta (es decir, globbing) se desactivan, por lo que
VAR=$VAR1
es exactamente equivalente aVAR="$VAR1"
, en todos los shells POSIX y en todos los sh anteriores a POSIX de los que he oído hablar. . (Ref. POSIX: comandos simples ). Por la misma razón, seVAR=*
establece de manera confiableVAR
en la cadena literal*
; por supuesto,VAR=a b
estableceVAR
quea
ya queb
es una palabra separada en primer lugar. En términos generales, las comillas dobles son innecesarias cuando la sintaxis de shell espera una sola palabra, por ejemplo encase … in
(pero no en el patrón), pero incluso allí debe tener cuidado: por ejemplo, POSIX especifica quelos objetivos de redirección (>$filename
) no requieren comillas en los scripts, pero algunos shells, incluido bash, requieren comillas dobles incluso en scripts. Ver ¿ Cuándo es necesaria la doble cita? para un análisis más completoNecesita las comillas dobles en otros casos, en particular en
export VAR="${VAR1}"
(que se puede escribir de manera equivalenteexport "VAR=${VAR1}"
) en muchos shells (POSIX deja este caso abierto). La similitud de este caso con asignaciones simples y la naturaleza dispersa de la lista de casos en los que no necesita comillas dobles, es por eso que recomiendo usar comillas dobles a menos que desee dividir y englobar.fuente
IFS
carácter porque quiero tener el hábito. La única excepción es que no cito el valor cuando hago una asignación variable (a menos que sea necesario, como cuando el valor contiene un espacio). Esto hace que el resaltado de sintaxis del editor sea más útil cuando hay sustituciones de comandos comoFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. En lugar de colorear todo el color de "cadena", obtengo resaltado de sintaxis del código anidado. Por eso también evito los backticks.>$file
está bien en los scripts POSIX, no está en bash incluso cuando no es interactivo (a menos que se cumpla con POSIX$POSIXLY_CORRECT
o--posix
...).VAR=$VAR1
, a veces me ha sorprendidolocal VAR=$VAR1
que recuerdo haber trabajado de manera diferente en algunos aspectos, al menos en algunos shells. Pero atm, no puedo reproducir la divergencia.local VAR=$VAR1
es comoexport VAR=$VAR1
, depende del shell.Cotización
Tenga en cuenta que la comilla doble se usa para la expansión variable, y la comilla simple se usa para las comillas fuertes, es decir, sin expansión.
Expansión:
Salida:
Puede valer la pena mencionar que debe usar la cita siempre que sea posible por varias razones, entre las cuales se considera la mejor práctica y la legibilidad. También porque Bash es peculiar a veces y a menudo por formas aparentemente ilógicas o irrazonables / inesperadas, y la cita cambia las expectativas implícitas a explícitas, lo que reduce esa superficie de error (o potencial para ello).
Y aunque es completamente legal no cotizar, y funcionará en la mayoría de los casos, esa funcionalidad se proporciona por conveniencia y probablemente sea menos portátil. La práctica totalmente formal garantizada para reflejar la intención y la expectativa es citar.
Sustitución
Ahora considere también que la construcción
"${somevar}"
se usa para operaciones de sustitución. Varios casos de uso, como reemplazo y matrices.Reemplazo (pelado):
Reemplazo (reemplazo):
Matrices:
Todo esto apenas está rascando la superficie de la
"${var}"
construcción de sustitución. La referencia definitiva para el script de shell Bash es la referencia en línea libre, TLDP The Linux Documentation Projecthttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
fuente
termina entonces:
Vale la pena mencionar como un ejemplo más claro del uso de curvas
fuente