Réponses:
$(command)
est la «substitution de commande». Comme vous semblez le comprendre, il exécute le command
, capture sa sortie et l'insère dans la ligne de commande qui contient le $(…)
; par exemple,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
est la «substitution de paramètres». De nombreuses informations peuvent être trouvées dans la page de manuel du shell, bash (1) , sous la rubrique « Expansion des paramètres »:
${parameter}
La valeur du paramètre est remplacée. Les accolades sont requises lorsque le paramètre est un paramètre positionnel à plusieurs chiffres ou lorsque le paramètre est suivi d'un caractère qui ne doit pas être interprété comme faisant partie de son nom.
Pour les paramètres de position, voir « Paramètres de position » ci-dessous. Dans son utilisation la plus courante, comme indiqué dans les autres réponses,
parameter
est un nom de variable. Le ${…}
formulaire, comme indiqué à la fin du paragraphe ci-dessus, vous permet d'obtenir la valeur d'une variable (c'est-à-dire ) et de la suivre immédiatement avec une lettre, un chiffre ou un trait de soulignement:$variable_name
$ animal = chat $ echo $ animaux # Aucune variable telle que «animaux». $ echo $ {animal} s chats $ echo $ animal_food # Aucune variable telle que «animal_food». $ echo $ {animal} _food la nourriture pour chat
Vous pouvez également le faire avec des guillemets:
$ echo "$ animal" s chats
Ou, comme exercice d'options, vous pouvez utiliser une deuxième variable:
$ plural = s $ echo $ animal $ pluriel chats
Mais ce n'est que l'étape 1. Le paragraphe suivant de la page de manuel est intéressant, bien qu'un peu cryptique:
Si le premier caractère du paramètre
est un point d'exclamation ( !
), un niveau d'indirection variable est introduit. Bash utilise la valeur de la variable formée à partir du reste du paramètre
comme nom de la variable; cette variable est ensuite développée et cette valeur est utilisée dans le reste de la substitution, plutôt que la valeur du paramètre lui-même. C'est ce qu'on appelle l' expansion indirecte .
… (Exceptions) …
Le point d'exclamation doit suivre immédiatement l'accolade gauche pour introduire l'indirection.
Je ne sais pas comment je peux clarifier cela, sauf par exemple:
$ animal = chat $ echo $ animal chat $ cat = tabby $ echo $ cat tigré $ echo $ {! animal} tabby # Si $ animal est "chat" , alors $ {! animal} est $ cat , c'est-à-dire "tabby"
Appelons donc cette étape 1½. Il y a beaucoup de choses intéressantes que vous pouvez faire à l'étape 2:
$ animal = chat $ echo $ {# animal} 3 # longueur de chaîne $ echo $ {animal / at / ow} vache # Substitution
Vous ne pouvez rien faire sans les {
… }
accolades.
Paramètres positionnels
Considérez cet exemple artificiel :
$ cat myecho.sh écho 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ $ ./myecho.sh Hey diddle diddle, Le chat et le violon, La vache a sauté sur la lune. Hey diddle diddle, Le chat et le violon, Le Hey0 Hey1 Hey2 Hey3 Hey4 Hey5
parce que la coquille ne comprend pas $10
, $11
etc. Il traite $10
comme si elle était ${1}0
. Mais il comprend ${10}
, ${11}
etc., comme mentionné dans la page de manuel ("un paramètre positionnel à plus d'un chiffre").
Mais n'écrivez pas vraiment des scripts comme ça; il existe de meilleures façons de gérer les longues listes d'arguments.
Ce qui précède (ainsi que de nombreuses autres formes de constructions) sont discutés plus longuement dans la page de manuel du shell, bash (1) .${parameter…something_else}
Une note sur les citations
Notez que vous devez toujours citer les variables du shell, sauf si vous avez une bonne raison de ne pas le faire, et vous êtes sûr de savoir ce que vous faites. En revanche, si les accolades peuvent être importantes, elles ne sont pas aussi importantes que les guillemets.
$ filename = "nursery rhyme.txt" $ ls -ld $ {filename} ls: impossible d'accéder à la pépinière: aucun fichier ou répertoire de ce type ls: impossible d'accéder à rhyme.txt: aucun fichier ou répertoire de ce type $ ls -ld "$ filename" -rwxr-xr-x 1 Noob Noob 5309 2 juil 11:09 nursery rhyme.txt
Cela s'applique également aux paramètres de position (c'est-à-dire aux arguments de ligne de commande, par exemple "$1"
) et à la substitution de commande:
$ ls -ld $ (date "+% B% Y"). txt ls: impossible d'accéder à juillet: aucun fichier ou répertoire de ce type ls: impossible d'accéder à 2015.txt: aucun fichier ou répertoire de ce type $ ls -ld "$ (date" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 juil 2 11:09 juillet 2015.txt
Voir Bash quotes unescaped on command substitution
pour un bref traité sur l'interaction entre les guillemets et $(
… )
.
!
.
${!animal}
fait référence à la variable $cat
au lieu de la valeur cat." Oui, c'est exactement le point. "Comment / at devient-il un" c "dans l'écho $ {animal / at / ow}?" Huh? / at ne devient pas "c"; «Chat» devient «vache» lorsque «at» est remplacé par «ow».
Dans votre exemple, $ var et $ {var} sont identiques. Cependant, les accolades sont utiles lorsque vous souhaitez développer la variable dans une chaîne:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Ainsi, les accolades offrent un moyen de substituer la variable afin d'obtenir le nom de la nouvelle variable, elle-même à substituer.
Je le vois généralement plus souvent dans les chaînes. Quelque chose comme ça ne fonctionnera pas:
var="a"
echo "$varRAW_STRING"
Mais cela:
var="a"
echo "${var}RAW_STRING"
Comme vous l'avez bien dit, $()
est utilisé pour exécuter une commande:
dir_contents=$(ls)
Vous pouvez également utiliser des backticks, mais je trouve le $()
plus polyvalent. D'une part, les backticks ne peuvent pas être (facilement) imbriqués.
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'\``
. Mais c'est terriblement moche; $(…)
est beaucoup plus clair et plus facile à utiliser.
`…`
était la (seule) syntaxe de substitution de commande pendant des années avant $(…)
a été inventé, de sorte que vous n'avez pas besoin d'imaginer quoi que ce soit - les gens l' ont fait.
${
variable_name
}