Tutti i costrutti di annidamento che possono essere interpolati all'interno di stringhe possono avere ulteriori stringhe al loro interno: vengono analizzati come un nuovo script, fino al marcatore di chiusura e possono anche essere nidificati a più livelli di profondità. Tutti tranne uno di questi inizia con a $
. Tutti sono documentati in una combinazione del manuale Bash e delle specifiche del linguaggio dei comandi della shell POSIX.
Ci sono alcuni casi di questi costrutti:
Sostituisci i comandi con$( ... )
, come hai trovato. POSIX specifica questo comportamento :
Con il $(command)
modulo, tutti i caratteri che seguono la parentesi aperta alla parentesi di chiusura corrispondente costituiscono il comando. Qualsiasi script shell valido può essere utilizzato per il comando ...
Le citazioni fanno parte di script shell validi, quindi sono consentite con il loro significato normale.
- Usando
`
anche la sostituzione dei comandi .
L'elemento "word" di istanze avanzate di sostituzione dei parametri come${parameter:-word}
. La definizione di "parola" è :
Una sequenza di personaggi trattati come un'unità dalla shell
- che include testo tra virgolette e persino virgolette miste a"b"c'd'e
- sebbene il comportamento reale delle espansioni sia un po 'più liberale di quello, e per esempio ${x:-hello world}
funziona anche.
Espansione aritmetica con $(( ... ))
, sebbene sia in gran parte inutile lì (ma puoi annidare anche la sostituzione dei comandi o espansioni variabili, e quindi avere virgolette all'interno di quelle). POSIX afferma che :
L'espressione deve essere trattata come se fosse tra virgolette doppie, tranne per il fatto che una virgoletta doppia all'interno dell'espressione non è trattata in modo speciale. La shell espande tutti i token nell'espressione per l'espansione dei parametri, la sostituzione dei comandi e la rimozione delle quotazioni.
quindi questo comportamento è esplicitamente richiesto. Ciò significa echo "abc $((4 "*" 5))"
che è aritmetica, piuttosto che sconvolgente.
Nota che l' $[ ... ]
espansione aritmetica vecchio stile non viene trattata allo stesso modo: le virgolette saranno un errore se compaiono, indipendentemente dal fatto che l'espansione sia quotata o meno. Questo modulo non è più documentato e non deve essere utilizzato comunque.
- Traduzione specifica delle impostazioni locali con
$"..."
, che attualmente utilizza l' "
elemento come elemento principale. $"
viene trattato come una singola unità.
C'è un altro caso di nidificazione che potresti non aspettarti, senza coinvolgere le virgolette, che è con l' espansione del controvento : si {a,b{c,d},e}
espande in "a bc bd e". ${x:-a{b,c}d}
fa non nido, tuttavia; viene trattato come una sostituzione di parametro che fornisce " a{b,c
", seguito da " d}
". Questo è anche documentato :
Quando vengono utilizzate le parentesi graffe, la parentesi finale corrispondente è il primo '}' non sfuggito a una barra rovesciata o all'interno di una stringa tra virgolette e non all'interno di un'espansione aritmetica incorporata, sostituzione di comando o espansione dei parametri.
Come regola generale, tutti i costrutti delimitati analizzano i loro corpi indipendentemente dal contesto circostante (e le eccezioni sono trattate come bug ). In sostanza, vedendo $(
il codice di sostituzione dei comandi chiede al parser di consumare ciò che può dal corpo come se fosse un nuovo programma, quindi verifica che l'indicatore di terminazione atteso (un escape )
o ))
o }
) appaia una volta eseguito il parser secondario dalle cose che può consumare.
Se si pensa al funzionamento di un parser a discesa ricorsiva , è solo una semplice ricorsione al caso base. In realtà è più facile da fare rispetto al contrario, una volta ottenuta l'interpolazione delle stringhe. Indipendentemente dalla tecnica di analisi sottostante, i gusci che supportano questi costrutti danno lo stesso risultato.
Puoi annidare citando quanto più ti piace attraverso questi costrutti e funzionerà come previsto. In nessun posto si confonderà vedendo una citazione nel mezzo; invece, sarà l'inizio di una nuova stringa tra virgolette nel contesto interno.