desarrollo-web-br-bd.com

¿Cuál es la diferencia entre las comillas "...", '...', $ '...' y $ "..."?

A veces veo que los scripts usan todas estas formas diferentes de citar algún texto: "...", '...', $'...' y $"...". ¿Por qué se utilizan tantos tipos diferentes de cotizaciones?

¿Se comportan de manera diferente o afectan lo que puedo hacer dentro de ellos?

52
Michael Homer

Todos estos significan algo diferente, y puedes escribir diferentes cosas dentro de ellos (o las mismas cosas, con un significado diferente). Diferentes tipos de comillas interpretan diferentes secuencias de escape dentro de ellas (\something), O permiten o no interpolaciones variables ($something) Y otros tipos de expansión dentro de ellas.

En breve:

  • '...' Es completamente literal.
  • "..." Permite tanto las variables como los caracteres de comillas incrustados.
  • $'...' Realiza escapes de caracteres como \n, Pero no expande las variables.
  • $"..." Es para traducciones en lenguaje humano en Bash y ksh.

'Comillas simples'

Lo que escriba entre comillas simples se trata literalmente y no se procesa en absoluto. Las barras invertidas y los signos de dólar no tienen un significado especial allí. Esto significa que no puede hacer una barra invertida para escapar de un carácter (¡incluidas otras comillas simples!), Interpolar una variable o usar cualquier otra función de Shell.

Todos estos ejemplos dan como resultado literalmente lo que está escrito entre comillas:

'hello world'                     => hello world
'/pkg/bin:$PATH'                  => /pkg/bin:$PATH
'hello\nworld'                    => hello\nworld
'`echo abc`'                      => `echo abc`
'I\'dn\'t've'                     => I\dn'tve

El último es complicado: hay ¡dos cadenas entre comillas simples se ejecutan junto con texto sin comillas. El primero contiene I\. El texto sin comillas dn\'t Contiene una comilla simple que se ha escapado en el nivel Shell, por lo que no inicia una cadena entre comillas y se incluye como un carácter literal (entonces, dn't). La cadena final entre comillas es solo ve. Todos ellos se unen en una sola palabra de la forma habitual en que funciona Shell.

Un modismo algo común para combinar texto literal y variables es ejecutarlos juntos de la siguiente manera:

'let x="'$PATH\"

resultará en

let x="/usr/bin:/bin"

como una sola palabra (mejor comillas dobles $PATH también por si acaso - los espacios o caracteres globales en la variable value pueden procesarse de otra manera - pero en aras de un ejemplo legible que no tengo).


"Comillas dobles"

Dentro de las comillas dobles, se procesan dos tipos de expansión, y puede usar una barra invertida para escapar caracteres para evitar que se procesen expansiones o escapes.

Hay dos categorías de expansión que ocurren entre comillas dobles:

Dentro de las comillas, una barra invertida puede inhibir esas expansiones poniéndola antes de $ O `. También puede escapar de una comilla doble de cierre, por lo que \" Incluye solo " En su cadena u otra barra diagonal inversa. Cualquier otra barra diagonal inversa se conserva literalmente: no hay escapes para producir otros caracteres, y no se elimina.

Algunos de estos ejemplos actúan de manera diferente a antes, y otros no:

"hello world"                     => hello world
"/pkg/bin:$PATH"                  => /pkg/bin:/bin:/usr/bin
"hello\nworld"                    => hello\nworld
"hello\\nworld"                   => hello\nworld
"`echo abc`"                      => abc
"I\'dn\'t've"                     => I\'dn\'t've
"I'dn't've"                       => I'dn't've
"I\"dn\"t've"                     => I"dn"t've

$ 'Cita ANSI-C'

Este tipo de comillas permite procesar los escapes de barra invertida de estilo C, pero ¡no variables o sustituciones incrustadas. Es el tipo de cita ¡solo que admite escapes de caracteres .

Esta es una extensión de ksh, ahora compatible con Bash, zsh y algunos otros shells también. No es todavía parte del estándar POSIX y, por lo tanto, los scripts máximamente portátiles no pueden usarlo, pero un script Bash o ksh es gratuito.

Todos estos escapes se pueden usar con sus significados en C: \a, \b, \f, \n, \r, \t, \v, Y el literal escapa \\, \', \" Y \?. También admiten las extensiones \e (Carácter de escape) y en Bash y ksh \cx (Lo que se ingresaría por Ctrl-x , por ejemplo, \cM es el retorno de carro). Los proyectiles tienen una gama de extensiones menores propias.

También permite cuatro tipos de escapes de caracteres genéricos:

  • \nnn, Un solo byte con valor octal nnn
  • \xHH, Un solo byte con valor hexadecimal [~ # ~] hh [~ # ~]
  • \uHHHH, El punto de código Unicode cuyo índice hexadecimal es [~ # ~] hhhh [~ # ~]
  • \UHHHHHHHH, El punto de código Unicode cuyo índice hexadecimal es [~ # ~] hhhhhhhh [~ # ~]

Todos esos dígitos son opcionales después del primero.

$ Y ` No tienen significado y se conservan literalmente, por lo que no puede incluir una variable allí.

$'hello world'                    => hello world
$'/pkg/bin:$PATH'                 => /pkg/bin:$PATH
$'hello\nworld'                   => hello
                                     world
$'`echo abc`'                     => `echo abc`
$'I\'dn\'t\'ve'                   => I'dn't've
$'\U1f574\u263A'                  => ????☺

La mayoría de estos escapes se pueden simular usando el comando printf , aunque POSIX solo requiere \\, \a, \b, \f, \n, \r, \t, \v, Y \nnn Para trabajar allí. Puede usar la sustitución de comandos para incrustar un printf dentro de comillas dobles si es necesario: "Path:$(printf '\t')$PATH".


$ "Traducción regional"

Esta es una extensión específica de ksh y Bash para localizar cadenas de texto en lenguaje natural, y busca la parte dentro de las comillas en un catálogo de mensajes. Realiza todas las expansiones de comillas dobles primero. Si la cadena no se encuentra en la base de datos de traducción, se usa como su propia traducción. La suposición incorporada es que las cadenas están en inglés.

Probablemente no quiera usar este, pero si lo ve, generalmente puede tratarlo como comillas dobles regulares.


Un punto a tener en cuenta es que hay ¡no tipo de cita que permite la expansión de parámetros incrustados y los escapes de caracteres incrustados. En la mayoría de los casos en los que desearía eso, sería mejor (más seguro) usar printf:

printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"

Esto separa claramente qué partes están sujetas al escape de caracteres y cuáles son valores de datos.

Otra es que todos estos estilos de citas crean una sola "Palabra" en el Shell, ¡a menos[email protected] O una expansión de matriz ${x[@]} Se utiliza dentro de comillas dobles . Ambas formas de comillas simples son siempre una sola Palabra y nunca se expandieron más.

68
Michael Homer