Risposte:
$(command)
è "sostituzione comando". Come sembra capire, esegue il command
, cattura il suo output e lo inserisce nella riga di comando che contiene il $(…)
; per esempio,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
è "sostituzione dei parametri". Molte informazioni sono disponibili nella pagina man della shell, bash (1) , sotto la voce " Espansione dei parametri ":
${parameter}
Il valore del parametro viene sostituito. Le parentesi graffe sono necessarie quando il parametro è un parametro posizionale con più di una cifra o quando il parametro è seguito da un carattere che non deve essere interpretato come parte del suo nome.
Per i parametri posizionali, vedere " Parametri posizionali ", di seguito. Nel suo utilizzo più comune, come mostrato nelle altre risposte,
parameter
è un nome variabile. Il ${…}
modulo, come indicato alla fine del paragrafo precedente, consente di ottenere il valore di una variabile (ovvero, ) e di seguirlo immediatamente con una lettera, una cifra o un trattino basso:$variable_name
$ animale = cat $ echo $ animali # Nessuna variabile come "animali". $ echo $ {animal} s gatti $ echo $ animal_food # Nessuna variabile come "animal_food". $ echo $ {animal} _food cibo per gatti
Puoi anche farlo con le virgolette:
$ echo "$ animal" s gatti
Oppure, come esercizio di opzioni, è possibile utilizzare una seconda variabile:
$ plurale = s $ echo $ animal $ plurale gatti
Ma questo è solo il passaggio 1. Il prossimo paragrafo nella pagina man è interessante, anche se un po 'enigmatico:
Se il primo carattere del parametro
è un punto esclamativo ( !
), viene introdotto un livello di indiretta variabile. Bash utilizza il valore della variabile formata dal resto del parametro
come nome della variabile; questa variabile viene quindi espansa e quel valore viene utilizzato nel resto della sostituzione, anziché il valore del parametro stesso. Questo è noto come espansione indiretta .
... (eccezioni) ...
Il punto esclamativo deve seguire immediatamente la parentesi graffa sinistra per introdurre il riferimento indiretto.
Non sono sicuro di come posso renderlo più chiaro se non per esempio:
$ animale = cat $ echo $ animal gatto $ cat = tabby $ echo $ cat soriano $ echo $ {! animal} tabby # Se $ animal è "cat" , allora $ {! animal} è $ cat , ovvero "tabby"
Quindi chiamiamo questo passaggio 1½. Ci sono molte cose interessanti che puoi fare come passaggio 2:
$ animale = cat $ echo $ {# animal} 3 # Lunghezza della stringa $ echo $ {animale / a / ow} mucca # Sostituzione
Non puoi fare nessuna di queste cose senza le {
... }
parentesi graffe.
Parametri posizionali
Considera questo esempio artificiale :
$ cat myecho.sh eco $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh Hey diddle diddle, Il gatto e il violino, La mucca saltò sulla luna. Hey diddle diddle, Il gatto e il violino, The Hey0 Hey1 Hey2 Hey3 Hey4 Hey5
perché la shell non capisce $10
, $11
ecc Si tratta $10
come se fosse ${1}0
. Ma capisce ${10}
, ${11}
ecc., Come menzionato nella pagina man ("un parametro posizionale con più di una cifra").
Ma in realtà non scrivere script del genere; ci sono modi migliori per gestire lunghi elenchi di argomenti.
Quanto sopra (insieme a molte altre forme di costrutti) sono discussi più a fondo nella pagina man della shell, bash (1) .${parameter…something_else}
Una nota sulle citazioni
Nota che dovresti sempre citare le variabili della shell a meno che tu non abbia una buona ragione per non farlo e sei sicuro di sapere cosa stai facendo. Al contrario, sebbene le parentesi graffe possano essere importanti, non sono importanti quanto le virgolette.
$ filename = "nursery rhyme.txt" $ ls -ld $ {nome file} ls: impossibile accedere all'asilo: nessun file o directory ls: impossibile accedere a rhyme.txt: nessun file o directory $ ls -ld "$ nomefile" -rwxr-xr-x 1 Noob Noob 5309 2 lug 11:09 nursery rhyme.txt
Ciò vale anche per i parametri posizionali (es. Argomenti della riga di comando; es. "$1"
) E anche per la sostituzione dei comandi:
$ ls -ld $ (data "+% B% Y"). txt ls: impossibile accedere a luglio: nessun file o directory ls: impossibile accedere a 2015.txt: nessun file o directory $ ls -ld "$ (data" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 2 luglio 11:09 luglio 2015.txt
Vedi le citazioni di Bash senza escape sulla sostituzione dei comandi
per un breve trattato sull'interazione tra virgolette e $(
… )
.
!
.
${!animal}
realtà si riferisce alla variabile $cat
anziché al valore cat". Sì, questo è esattamente il punto. "Come fa / a diventare una" c "in echo $ {animal / at / ow}?” Eh? / at non diventa "c"; "Cat" diventa "cow" quando "at" è sostituito da "ow".
Nel tuo esempio, $ var e $ {var} sono identici. Tuttavia, le parentesi graffe sono utili quando si desidera espandere la variabile in una stringa:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Pertanto, le parentesi graffe forniscono un mezzo per sostituire la variabile al fine di ottenere il nome della nuova variabile, che deve essere sostituita.
Di solito lo vedo più comunemente nelle stringhe. Qualcosa del genere non funzionerà:
var="a"
echo "$varRAW_STRING"
Ma questo:
var="a"
echo "${var}RAW_STRING"
Come hai detto correttamente, $()
viene utilizzato per eseguire un comando:
dir_contents=$(ls)
Puoi anche usare i backtick, ma trovo il $()
più versatile. Per prima cosa, i backtick non possono essere (facilmente) nidificati.
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
. Ma è terribilmente brutto; $(…)
è molto più chiaro e più facile da usare.
`…`
stata la (sola) sintassi per la sostituzione del comando per anni prima che $(…)
fosse inventata, quindi non è necessario immaginare nulla: la gente l'ha fatto.
${
variable_name
}