Diferencia entre comillas simples y dobles en Bash
En Bash, ¿cuáles son las diferencias entre comillas simples ( ''
) y comillas dobles ( ""
)?
Las comillas simples no interpolarán nada, pero las comillas dobles sí lo harán. Por ejemplo: variables, comillas invertidas, ciertos \
escapes, etc.
Ejemplo:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
El manual de Bash tiene esto que decir:
3.1.2.2 Comillas simples
Al encerrar caracteres entre comillas simples (
'
), se conserva el valor literal de cada carácter entre comillas. No puede aparecer una comilla simple entre comillas simples, incluso si van precedidas de una barra invertida.3.1.2.3 Comillas dobles
Al encerrar caracteres entre comillas dobles (
"
), se conserva el valor literal de todos los caracteres entre comillas, con la excepción de$
,`
,\
y, cuando la expansión del historial está habilitada,!
. Los caracteres$
y`
conservan su significado especial entre comillas dobles (consulte Expansiones de Shell ). La barra invertida conserva su significado especial sólo cuando va seguida de uno de los siguientes caracteres: , ,$
,`
o nueva línea. Entre comillas dobles, se eliminan las barras invertidas seguidas de uno de estos caracteres. Las barras invertidas que preceden a caracteres sin un significado especial no se modifican. Una comilla doble se puede citar entre comillas dobles precediéndola de una barra invertida. Si está habilitado, se realizará la expansión del historial a menos que aparezca entre comillas dobles y se escape mediante una barra invertida. La barra invertida que precede a no se elimina."
\
!
!
Los parámetros especiales
*
y@
tienen un significado especial cuando están entre comillas dobles (consulte Expansión de parámetros de Shell ).
La respuesta aceptada es genial. Estoy haciendo una tabla que ayuda a la rápida comprensión del tema. La explicación involucra una variable simple a
así como una matriz indexada arr
.
si establecemos
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
y luego echo
la expresión en la segunda columna, obtendríamos el resultado/comportamiento que se muestra en la tercera columna. La cuarta columna explica el comportamiento.
# | Expresión | Resultado | Comentarios |
---|---|---|---|
1 | "$a" |
apple |
las variables se expanden dentro"" |
2 | '$a' |
$a |
las variables no se expanden dentro'' |
3 | "'$a'" |
'apple' |
'' no tiene ningún significado especial en el interior"" |
4 | '"$a"' |
"$a" |
"" es tratado literalmente por dentro'' |
5 | '\'' |
inválido | no puede escapar de un ' interior '' ; utilizar "'" o $'\'' (cita ANSI-C) |
6 | "red$arocks" |
red |
$arocks no se expande $a ; utilizar ${a}rocks para preservar$a |
7 | "redapple$" |
redapple$ |
$ seguido de ningún nombre de variable se evalúa como$ |
8 | '\"' |
\" |
\ no tiene ningún significado especial en el interior'' |
9 | "\'" |
\' |
\' se interpreta en el interior "" pero no tiene importancia para' |
10 | "\"" |
" |
\" se interpreta por dentro"" |
11 | "*" |
* |
glob no funciona dentro "" o'' |
12 | "\t\n" |
\t\n |
\t y \n no tienen ningún significado especial dentro "" o '' ; utilizar cotizaciones ANSI-C |
13 | "`echo hi`" |
hi |
`` y $() se evalúan en el interior "" (las comillas inversas se conservan en la salida real) |
14 | '`echo hi`' |
`echo hi` |
`` y $() no se evalúan internamente '' (las comillas inversas se conservan en la salida real) |
15 | '${arr[0]}' |
${arr[0]} |
acceso a la matriz no es posible dentro'' |
dieciséis | "${arr[0]}" |
apple |
el acceso a la matriz funciona dentro"" |
17 | $'$a\'' |
$a' |
Las comillas simples se pueden escapar dentro de las comillas ANSI-C. |
18 | "$'\t'" |
$'\t' |
Las citas ANSI-C no se interpretan en el interior"" |
19 | '!cmd' |
!cmd |
El carácter de expansión de la historia '!' se ignora en el interior.'' |
20 | "!cmd" |
cmd args |
se expande a la coincidencia de comando más reciente"cmd" |
21 | $'!cmd' |
!cmd |
El carácter de expansión del historial '!' se ignora dentro de las comillas ANSI-C. |
Ver también:
- Citas ANSI-C con
$''
- GNU Bash Manual - Traducción local con
$""
- GNU Bash Manual - Una fórmula de tres puntos para las cotizaciones
Si te refieres a lo que sucede cuando repites algo, las comillas simples literalmente harán eco de lo que tienes entre ellas, mientras que las comillas dobles evaluarán las variables entre ellas y generarán el valor de la variable.
Por ejemplo, este
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
dará esto:
double quotes gives you sometext
single quotes gives you $MYVAR
Otros lo explicaron muy bien y yo solo quiero dar algo con ejemplos sencillos.
Se pueden utilizar comillas simples alrededor del texto para evitar que el shell interprete caracteres especiales. Los signos de dólar, espacios, símbolos comerciales, asteriscos y otros caracteres especiales se ignoran cuando se incluyen entre comillas simples.
echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Dará esto:
All sorts of things are ignored in single quotes, like $ & * ; |.
Lo único que no se puede poner entre comillas simples son las comillas simples.
Las comillas dobles actúan de manera similar a las comillas simples, excepto que las comillas dobles aún permiten que el shell interprete los signos de dólar, las comillas invertidas y las barras invertidas. Ya se sabe que las barras invertidas impiden que se interprete un solo carácter especial. Esto puede resultar útil entre comillas dobles si es necesario utilizar un signo de dólar como texto en lugar de para una variable. También permite escapar de las comillas dobles para que no se interpreten como el final de una cadena entre comillas.
echo "Here's how we can use single ' and double \" quotes within double quotes"
Dará esto:
Here's how we can use single ' and double " quotes within double quotes
También se puede observar que el apóstrofo, que de otro modo se interpretaría como el comienzo de una cadena entre comillas, se ignora entre comillas dobles. Sin embargo, las variables se interpretan y sustituyen con sus valores entre comillas dobles.
echo "The current Oracle SID is $ORACLE_SID"
Dará esto:
The current Oracle SID is test
Las comillas invertidas son totalmente diferentes a las comillas simples o dobles. En lugar de usarse para evitar la interpretación de caracteres especiales, las comillas inversas en realidad fuerzan la ejecución de los comandos que encierran. Después de ejecutar los comandos adjuntos, su salida se sustituye en lugar de las comillas invertidas en la línea original. Esto quedará más claro con un ejemplo.
today=`date '+%A, %B %d, %Y'`
echo $today
Dará esto:
Monday, September 28, 2015
Dado que esta es la respuesta de facto cuando se trata de comillas en Bash, agregaré un punto más que se perdió en las respuestas anteriores, cuando se trata de los operadores aritméticos en el shell.
El shell Bash admite dos formas de realizar operaciones aritméticas, una definida por el comando integrado let
y la otra por el $((..))
operador. El primero evalúa una expresión aritmética mientras que el segundo es más bien una declaración compuesta.
Es importante comprender que la expresión aritmética utilizada con let
sufre una expansión de nombre de ruta y división de palabras como cualquier otro comando de shell. Por lo tanto, es necesario citar y escapar adecuadamente.
Vea este ejemplo cuando use let
:
let 'foo = 2 + 1'
echo $foo
3
Usar comillas simples aquí está absolutamente bien, ya que no hay necesidad de expansiones variables aquí. Consideremos un caso de
bar=1
let 'foo = $bar + 1'
Fallaría estrepitosamente, ya que las $bar
comillas simples no se expandirían y deben citarse dos veces como
let 'foo = '"$bar"' + 1'
Esta debería ser una de las razones por las que $((..))
siempre se debe considerar el uso excesivo let
. Porque en su interior los contenidos no están sujetos a división de palabras. El ejemplo anterior usando let
se puede escribir simplemente como
(( bar=1, foo = bar + 1 ))
Recuerde siempre utilizar $((..))
sin comillas simples
Aunque se $((..))
puede utilizar con comillas dobles, no tiene ningún propósito ya que no puede contener contenido que necesite las comillas dobles. Solo asegúrese de que no esté entre comillas simples.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Tal vez en algunos casos especiales de uso del $((..))
operador dentro de una cadena entre comillas simples, necesite interpolar las comillas de manera que el operador quede sin comillas o entre comillas dobles. Por ejemplo, considere un caso en el que intenta utilizar el operador dentro de una curl
declaración para pasar un contador cada vez que se realiza una solicitud.
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Observe el uso de comillas dobles anidadas en el interior, sin las cuales la cadena literal $((reqcnt++))
se pasa al requestCounter
campo.
Existe una clara distinción entre el uso de ' '
y " "
.
Cuando ' '
se usa en torno a cualquier cosa, no se realiza ninguna "transformación o traducción". Está impreso tal cual.
Con " "
, lo que rodea, se "traduce o transforma" en su valor.
Por traducción/transformación me refiero a lo siguiente: todo lo que esté entre comillas simples no se "traducirá" a sus valores. Se tomarán tal como están entre comillas. Ejemplo: a=23
, luego echo '$a'
producirá $a
en salida estándar. Mientras que echo "$a"
producirá 23
en producción estándar.