A veces veo que los scripts de shell usan todas estas formas diferentes de citar un texto:"..."
, '...'
, $'...'
y $"..."
. ¿Por qué se utilizan tantos tipos diferentes de citas?
¿Se comportan de manera diferente o afectan lo que puedo hacer dentro de ellos?
Respuesta aceptada:
Todos estos significan algo diferente, y puedes escribir cosas diferentes 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 permite o no permite interpolaciones de variables ($something
) y otros tipos de expansión dentro de ellos.
En resumen:
'...'
es totalmente literal.
"..."
permite tanto variables como caracteres de comillas incrustados.
$'...'
realiza escapes de caracteres como n
, pero no expande las variables.
$"..."
es para traducciones de lenguaje humano en Bash y ksh.
'Comillas simples'
Todo lo que escriba entre comillas simples se trata literalmente y no se procesa en absoluto. Las barras diagonales inversas y los signos de dólar no tienen ningún significado especial allí. Esto significa que no puede usar una barra invertida y 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:
Código | Resultado |
'hello world' | hola mundo |
'/pkg/bin:$PATH' | /pkg/bin:$RUTA |
'hellonworld' | holamundo |
'`echo abc`' | `echo abc` |
'I'dn't've' | Idn'tve |
El último es complicado:hay dos las cadenas entre comillas simples se ejecutan junto con algún texto sin comillas. El primero contiene I
. El texto sin comillas dn't
contiene una comilla simple que se escapa en el nivel de shell , por lo que no comienza una cadena entrecomillada y se incluye como un carácter literal (entonces, dn't
). La cadena final citada es solo ve
. Todos ellos se juntan en una sola palabra de la forma habitual en que funciona el shell.
Un modismo algo común para combinar texto literal y variables es ejecutarlos juntos así:
'let x="'$PATH"
resultará en
let x="/usr/bin:/bin"
como una sola palabra (mejor entre comillas dobles $PATH
también por si acaso:espacios o caracteres globales en la variable valor puede procesarse de otra manera, pero por el bien de un ejemplo de ejecución legible, no lo he hecho).
“Comillas dobles”
Dentro de las comillas dobles, se procesan dos tipos de expansión, y puede usar una barra invertida para escapar de los caracteres para evitar que se procesen expansiones o escapes.
Hay dos categorías de expansión que ocurren entre comillas dobles:
- Aquellos que comienzan con
$
(expansión de parámetros $abc
y ${abc}
, sustitución de comando $(...)
, y expansión aritmética $((...))
);
- Sustitución de comandos con comillas invertidas
`abc`
;
Dentro de las comillas, una barra invertida puede inhibir esas expansiones colocá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 invertida. Cualquier otra barra invertida se conserva literalmente:no hay escapes para producir otros caracteres y no se elimina.
Algunos de estos ejemplos actúan de forma diferente a los anteriores y otros no:
Código | Resultado |
"hello world" | hola mundo |
"/pkg/bin:$PATH" | /pkg/bin:/bin:/usr/bin |
"hellonworld" | holamundo |
"hello\nworld" | holamundo |
"`echo abc`" | abc |
"I'dn't've" | No lo hubiera hecho |
"I'dn't've" | No lo hubiera hecho |
"I"dn"t've" | No lo he hecho |
Relacionado:Dhcpv6 – stateful VS stateless, ¿cuál es la diferencia entre ellos? $'Citas ANSI-C'
Este tipo de comillas permite que se procesen los escapes de barra invertida estilo C, pero no variables incrustadas o sustituciones. Es el único tipo de cita que admite escapes de caracteres .
Esta es una extensión de ksh, ahora compatible con Bash, zsh y algunos otros shells también. Todavía no es parte del estándar POSIX y, por lo tanto, los scripts de máxima portabilidad no pueden usarlo, pero un script Bash o ksh es gratuito.
Todos estos escapes se pueden usar con sus significados 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 con Ctrl-x, por ejemplo, cM
es retorno de carro). Las conchas tienen una variedad 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í.
Código | Resultado |
$'hello world' | hola mundo |
$'/pkg/bin:$PATH' | /pkg/bin:$RUTA |
$'hellonworld' | hola mundo |
$'`echo abc`' | `echo abc` |
$'I'dn't've' | No lo hubiera hecho |
$'U1f574u263A' | 🕴☺ |
La mayoría de estos escapes se pueden simular usando printf
comando, 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 local”
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. Primero realiza todas las expansiones de comillas dobles. 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 no hay no tipo de comillas que permite tanto la expansión de parámetros incrustados como los escapes de caracteres incrustados. En la mayoría de los casos en los que desearía eso, estaría mejor (más seguro) usando printf
:
printf 'New path: e[1m%se[0m' "/pkg/bin:$PATH:"
Esto separa claramente qué partes están sujetas a 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 que [email protected]
o una expansión de matriz ${x[@]}
se usa dentro de comillas dobles. Ambas formas de comillas simples son siempre una palabra y nunca se expanden más.