Qu'est-ce que cela signifie dans le shell lorsque nous mettons une commande entre le signe dollar et les parenthèses: $ (commande)

110

Je veux juste comprendre la ligne de code suivante dans le shell. Il est utilisé pour obtenir le répertoire de travail actuel. Je sais que le $(variable)nom renvoie la valeur à l'intérieur du nom de la variable, mais qu'est-ce qui est $(command)censé renvoyer? Renvoie-t-il la valeur après l'exécution de la commande? Dans ce cas, nous pouvons utiliser `pour exécuter la commande.

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

La même sortie peut être extraite de la ligne de code suivante également dans une version différente du shell

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

Je suis incapable de comprendre la signification de $(cd..et $(dirname.

Quelqu'un pourrait-il m'aider à comprendre comment cette commande est exécutée?

KItis
la source
1
Et voici une question sur les avantages / inconvénients de $()vs ``: stackoverflow.com/questions/9449778/…
Aucun

Réponses:

115

L'utilisation de $similaires ${HOME}donne la valeur de HOME. L'utilisation de la $même $(echo foo)chose signifie exécuter tout ce qui se trouve à l'intérieur des parenthèses dans un sous-shell et le renvoyer comme valeur. Dans mon exemple, vous obtiendrez foopuisque echoécrira fooen standard

Eric Urbain
la source
37
Oui; $(...)est une meilleure façon d'écrire une commande que d'essayer d'utiliser des guillemets. Pensez à écrire: en gcclib=$(dirname $(dirname $(which gcc)))/libutilisant des guillemets. Même avant d'entrer dans les difficultés de le faire dans Markdown, c'est plus difficile car vous devez échapper aux guillemets des commandes imbriquées, alors que vous ne le faites pas avec la $(...)notation.
Jonathan Leffler
7
Techniquement, $(echo foo)crée une substitution de commande, pas un sous-shell. L'autre réponse actuelle a raison. Je pense que la substitution de commandes est exécutée dans un sous-shell, en quelque sorte, mais ce sont toujours des concepts différents.
trysis le
4
@trysis - la substitution de commande s'exécute définitivement dans un sous-shell , et cela vaut donc la peine de le noter.
Eliran Malka le
2
Je comprends que les backticks produisent le même résultat que $ (), mais la différence est-elle purement cosmétique? y a-t-il une raison d'utiliser l'un contre l'autre, à part que le $ () est plus lisible?
Mitchell Tracy
2
"L'utilisation de $ like $ (echo foo) signifie exécuter tout ce qui se trouve entre parenthèses dans un sous-shell et le renvoyer comme valeur." ... Ceci est déroutant, car cette commande $(echo foo)essaiera d' exécuter ce qui est retourné par les parenthèses, elle s'exécutera d'abord, echo foopuis essaiera de s'exécuter, fooce qui donne une erreur
Accountant م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Quelqu'un pourrait-il m'aider à comprendre comment cette commande est exécutée?

Regardons différentes parties de la commande. BASH_SOURCEest une variable de tableau bash contenant les noms de fichiers source. Donc "${BASH_SOURCE[0]}"je vous renvoie le nom du fichier de script.

dirnameest un utilitaire fourni par GNU coreutils qui supprime le dernier composant du nom de fichier. Ainsi, si vous exécutez votre script en disant bash foo, "$( dirname "${BASH_SOURCE[0]}" )"reviendrait .. Si vous disiez bash ../foo, il reviendrait ..; car bash /some/path/fooil reviendrait /some/path.

Enfin, la commande entière "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"obtient le répertoire absolu contenant le script appelé.

$(...) permet la substitution de commande, c'est-à-dire permet à la sortie d'une commande de remplacer la commande elle-même et peut être imbriquée.

devnull
la source
1
Désolé d'avoir 3 ans de retard à la fête, mais pourriez-vous s'il vous plaît expliquer pourquoi la déclaration fonctionne? Vous avez dit dirnamerenvoie le chemin du fichier exécuté (relatif ou absolu au répertoire de travail actuel), cdmodifie le pwd dans ce répertoire et pwdaffiche le chemin absolu du répertoire de travail actuel. Mais pourquoi sont-ils rejoints &&? Et que se passera-t-il DIRsi l' cdéchec?
Christian
2
@Christian, &&empêche le pwdde s'exécuter en cas d' cdéchec, de sorte qu'il DIRsera vide plutôt que d'avoir un répertoire incorrect.
Charles Duffy