Cualquiera de las construcciones de anidamiento que se pueden interpolar dentro de las cadenas puede tener más cadenas dentro de ellas: se analizan como un nuevo script, hasta el marcador de cierre, e incluso se pueden anidar en varios niveles de profundidad. Todos menos uno de esos comienzan con a $
. Todos ellos están documentados en una combinación del manual de Bash y la especificación del lenguaje de comandos de shell POSIX.
Hay algunos casos de estas construcciones:
Sustitución de comandos con$( ... )
, como has encontrado. POSIX especifica este comportamiento :
Con el $(command)
formulario, todos los caracteres que siguen el paréntesis abierto al paréntesis de cierre coincidente constituyen el comando. Se puede usar cualquier script de shell válido para el comando ...
Las citas son parte de los scripts de shell válidos, por lo que se permiten con su significado normal.
- Sustitución de comandos usando
`
, también.
El elemento "palabra" de instancias de sustitución de parámetros avanzados como${parameter:-word}
. La definición de "palabra" es :
Una secuencia de caracteres tratados como una unidad por el shell
, que incluye texto citado e incluso citas mixtas a"b"c'd'e
, aunque el comportamiento real de las expansiones es un poco más liberal que eso, y por ejemplo ${x:-hello world}
también funciona.
La expansión aritmética con $(( ... ))
, aunque es en gran medida inútil allí (pero también puede anidar la sustitución de comandos o expansiones variables, y luego tener comillas útiles dentro de ellas). POSIX afirma que :
La expresión se tratará como si estuviera entre comillas dobles, excepto que una comilla doble dentro de la expresión no se trata especialmente. El shell expandirá todos los tokens en la expresión para expansión de parámetros, sustitución de comandos y eliminación de comillas.
entonces este comportamiento es explícitamente requerido. Eso significa echo "abc $((4 "*" 5))"
aritmética, en lugar de globbing.
Sin embargo, $[ ... ]
tenga en cuenta que la expansión aritmética de estilo antiguo no se trata de la misma manera: las comillas serán un error si aparecen, independientemente de si la expansión se cita o no. Este formulario ya no está documentado, y no está destinado a ser utilizado de todos modos.
- Traducción específica de la configuración regional
$"..."
, que en realidad usa el "
como elemento central. $"
se trata como una sola unidad
Hay otro caso de anidación que no puede esperar, que no involucra comillas, que es con expansión de llaves : se {a,b{c,d},e}
expande a "a bc bd e". ${x:-a{b,c}d}
hace no nido, sin embargo; se trata como una sustitución de parámetro que da " a{b,c
", seguido de " d}
". Eso también está documentado :
Cuando se usan llaves, la llave final coincidente es el primer '}' que no se escapa por una barra invertida o dentro de una cadena entre comillas, y no dentro de una expansión aritmética incorporada, sustitución de comando o expansión de parámetros.
Como regla general, todas las construcciones delimitadas analizan sus cuerpos independientemente del contexto circundante (y las excepciones se tratan como errores ). En esencia, al ver $(
el código de sustitución de comandos solo le pide al analizador que consuma lo que pueda del cuerpo como si fuera un nuevo programa, y luego verifica que el marcador de terminación esperado (sin escape )
o ))
o }
) aparezca una vez que se ejecuta el sub-analizador fuera de las cosas que puede consumir.
Si piensa en el funcionamiento de un analizador de descenso recursivo , eso es solo una simple recurrencia al caso base. En realidad, es más fácil de hacer que a la inversa, una vez que tienes la interpolación de cadenas. Independientemente de la técnica de análisis subyacente, los depósitos que soportan estas construcciones dan el mismo resultado.
Puede anidar las citas tan profundamente como desee a través de estas construcciones y funcionará como se espera. Ningún lugar se confundirá al ver una cita en el medio; en cambio, ese será el comienzo de una nueva cadena entre comillas en el contexto interior.