
Une commande cmd entourée par une paire de parenthèses () précédées d'un caractère $ est exécutée par le shell puis la chaîne $( cmd ) est remplacée par les résultats de la commande cmd écrits sur la sortie standard, c’est à dire l’écran. Ces résultats peuvent alors être affectés à une
rnvariable ou bien servir à initialiser des paramètres de position.
Syntaxe : $( cmd )
Exemple :
$ pwd
/home/tony => résultat écrit par pwd sur sa sortie standard
$ repert=$(pwd) => la chaîne /home/tony remplace la chaîne $(pwd)
$
$ echo mon repertoire est $repert
mon repertoire est /home/tony
$
Lorsque la substitution de commande est utilisée avec la commande interne set, l’erreur suivante peut se produire :
$ set $( ls -l .bashrc)
bash: set: -w: invalid option
set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
$ ls -l .bashrc
-rw-r--r-- 1 tony users 1342 nov 29 2014 .bashrc
$
Le premier mot issu de la substitution commence par un caractère tiret : la commande interne set l'interprète comme une option, ce qui provoque une erreur. Pour résoudre ce type de problème, on double le caractère tiret.
$ set -- $(ls -l .bashrc)
$
$ echo $1
-rw-r--r-- 1 tony users 1342 nov 29 2014 .bashrc
$
Plusieurs commandes peuvent être présentes entre les parenthèses.
Exemple :
$ pwd ; whoami
/home/tony
tony
$
$ set $(pwd ; whoami)
$
$ echo $2: $1
tony: /home/tony
$
Les substitutions de commandes peuvent être imbriquées.
Exemple :
$ ls .gnome
application-info gnome-vfs mime-info
$
$ set $( ls $(pwd)/.gnome )
$
$ echo $# => nombre d'entrées du répertoire .gnome
3
$
Plusieurs sortes de substitutions (de commandes, de variables) peuvent être présentes dans la même commande.
Exemple :
$ read rep
gnome
$
$ set $( ls $( pwd )/$rep ) => substitutions de deux commandes et d'une variable
$
La substitution de commande permet également de capter les résultats écrits par un fichier shell.
Exemple : (on suppose que le contenu du fichier jour contient le code echo 22)
$ ./jour
22
$
$ resultat=$( ./jour )
$
La variable resultat contient la chaîne 22.
Remarque :
Il existe pour la substitution de commande une syntaxe plus ancienne `cmd ` (deux caractères accent grave entourent la commande cmd), à utiliser lorsque se posent des problèmes de portabilité.
Créé par des informaticiens américains, le système Unix était originellement destiné à des utilisateurs anglophones. La diffusion des systèmes de la famille Unix (dont GNU/Linux) vers des publics de langues et de cultures différentes a conduit leurs développeurs à introduire des paramètres régionaux (locale). Ces derniers permettent par exemple de fixer la langue d'affichage des messages, le format des dates ou des nombres. Les paramètres régionaux se présentent à l'utilisateur sous la forme de variables prédéfinies dont le nom commence par LC_.
La commande unix locale utilisée sans argument affiche la valeur courante de ces variables d'environnement.
$ locale
LANG=fr_FR@euro
LC_CTYPE="fr_FR@euro"
LC_NUMERIC="fr_FR@euro"
LC_TIME="fr_FR@euro"
LC_COLLATE="fr_FR@euro"
LC_MONETARY="fr_FR@euro"
LC_MESSAGES="fr_FR@euro"
LC_PAPER="fr_FR@euro"
LC_NAME="fr_FR@euro"
LC_ADDRESS="fr_FR@euro"
LC_TELEPHONE="fr_FR@euro"
LC_MEASUREMENT="fr_FR@euro"
LC_IDENTIFICATION="fr_FR@euro"
LC_ALL=
$
Des commandes telles que date utilisent la valeur de ces variables prédéfinies pour afficher leurs résultats.
Exemple : $ date
lundi 26 octobre 2015, 18:47:02 (UTC+0100)
$
On remarque que le format du résultat correspond bien à une date « à la française » (jour de la semaine, jour du mois, mois, année). Si cette internationalisation procure un confort indéniable lors d'une utilisation interactive du système, elle pose problème lorsque l'on doit écrire un
programme shell se basant sur la sortie d'une telle commande, sortie qui dépend étroitement de la valeur des paramètres régionaux. La portabilité du programme shell en est fortement fragilisée. Cependant, le fonctionnement standard d’un système unix traditionnel peut être obtenu en choisissant la « locale standard » appelée C. Pour que cette locale n’affecte temporairement que les résultats d’une seule commande, par exemple date, il suffit d’exécuter la commande
LC_ALL=C date
Exemple :
$ LC_ALL=C date
Mon Oct 26 18:47:41 CET 2015
$
On s’aperçoit qu’avec la locale standard, le jour du mois est en troisième position alors qu’avec la locale précédente, il était en deuxième position. Pour obtenir de manière portable le jour courant du mois, on pourra exécuter les commandes suivantes :
Exemple :
$ set $(LC_ALL=C date) ; echo $3
3
$