Cosa significa nella shell quando mettiamo un comando tra il segno del dollaro e le parentesi: $ (comando)


110

Voglio solo capire la seguente riga di codice nella shell. Viene utilizzato per ottenere la directory di lavoro corrente. Sono consapevole che $(variable)name restituisce il valore all'interno del nome della variabile, ma cosa $(command)dovrebbe restituire? Restituisce il valore dopo aver eseguito il comando? In tal caso, possiamo usare `per eseguire il comando.

CWD="$(cd "$(dirname $0)"; pwd)"

Lo stesso output può essere preso dalla seguente riga di codice anche in versioni differenti della shell

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Non riesco a capire il significato di $(cd..e $(dirname.

Qualcuno potrebbe aiutarmi a capire come viene eseguito questo comando?


1
Ed ecco una domanda sui vantaggi / svantaggi di $()vs ``.: stackoverflow.com/questions/9449778/…
Nessuno

Risposte:


115

L'uso di $simili ${HOME}dà il valore di CASA. L'utilizzo di $like $(echo foo)significa eseguire tutto ciò che è tra parentesi in una subshell e restituirlo come valore. Nel mio esempio, si otterrebbe foodal momento echoche scriverà foosu standard out


37
Sì; $(...)è un modo migliore per scrivere un comando che provare a usare le virgolette. Considera la scrittura: gcclib=$(dirname $(dirname $(which gcc)))/libusando le virgolette all'indietro. Anche prima di entrare nelle difficoltà di farlo in Markdown, è più difficile perché devi sfuggire alle virgolette dei comandi annidati, mentre non lo fai con la $(...)notazione.
Jonathan Leffler

7
Tecnicamente, $(echo foo)crea una sostituzione del comando, non una subshell. L'altra risposta attuale ha ragione. Penso che la sostituzione dei comandi venga eseguita in una subshell, una specie di, ma sono ancora concetti diversi.
trysis

4
@trysis: la sostituzione del comando viene sicuramente eseguita in una subshell , quindi vale la pena notarla.
Eliran Malka

2
Capisco che i backtick producono lo stesso risultato di $ (), ma la differenza è puramente estetica? c'è un motivo per usarne uno rispetto all'altro, a parte il fatto che $ () è più leggibile?
Mitchell Tracy

2
"L'utilizzo di $ like $ (echo foo) significa eseguire tutto ciò che è tra parentesi in una subshell e restituirlo come valore." ... Questo è fonte di confusione, poiché questo comando $(echo foo)proverà a eseguire ciò che viene restituito dalle parentesi, verrà eseguito prima, echo fooquindi proverà a eseguire il fooche dà un errore
Accountant م

21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Qualcuno potrebbe aiutarmi a capire come viene eseguito questo comando?

Diamo un'occhiata alle diverse parti del comando. BASH_SOURCEè una variabile array bash contenente nomi di file sorgente. Quindi "${BASH_SOURCE[0]}"ti restituirebbe il nome del file di script.

dirnameè un'utilità fornita da GNU coreutils che rimuove l' ultimo componente dal nome del file. Quindi, se esegui il tuo script dicendo bash foo, "$( dirname "${BASH_SOURCE[0]}" )"tornerebbe .. Se bash ../foolo dicessi, tornerebbe ..; per bash /some/path/fooesso sarebbe tornato /some/path.

Infine, l'intero comando "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"ottiene la directory assoluta contenente lo script richiamato.

$(...) consente la sostituzione del comando, ovvero consente all'output di un comando di sostituire il comando stesso e può essere annidato.


1
Scusa per il ritardo di 3 anni alla festa, ma potresti spiegare perché l'affermazione funziona? Hai detto che dirnamerestituisce il percorso del file eseguito (relativo o assoluto alla directory di lavoro attuale), cdcambia il pwd in quella directory e pwdstampa il percorso assoluto della directory di lavoro corrente. Ma perché si sono uniti a loro &&? E cosa DIRmanterrà se cdfallisce?
Christian

2
@Christian, &&impedisce l' pwdesecuzione in caso di cderrore, in modo tale che DIRsarà vuoto anziché avere una directory errata.
Charles Duffy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.