Diferencia entre comillas simples y dobles en Bash

Resuelto jrdioko asked hace 13 años • 7 respuestas

En Bash, ¿cuáles son las diferencias entre comillas simples ( '') y comillas dobles ( "")?

jrdioko avatar Jul 15 '11 00:07 jrdioko
Aceptado

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 ).

Adam Batkin avatar Jul 14 '2011 17:07 Adam Batkin

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 aasí como una matriz indexada arr.

si establecemos

a=apple      # a simple variable
arr=(apple)  # an indexed array with a single element

y luego echola 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 $arocksno se expande $a; utilizar ${a}rockspara 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 \ty \nno 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
codeforester avatar Feb 07 '2017 06:02 codeforester

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
likso avatar Jul 14 '2011 18:07 likso

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
SreehariGaddam avatar Jul 14 '2018 18:07 SreehariGaddam

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 lety 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 letsufre 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 $barcomillas 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 letse 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 curldeclaració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 requestCountercampo.

Inian avatar Jan 02 '2019 16:01 Inian

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á $aen salida estándar. Mientras que echo "$a"producirá 23en producción estándar.

a_r avatar Aug 19 '2018 08:08 a_r