Chapitre 3. Substitution de commandes

Table des matières

3.1. Présentation
3.2. Substitutions de commandes et paramètres régionaux

3.1. Présentation

Syntaxe : $( cmd )

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 variable ou bien servir à initialiser des paramètres de position.

$ pwd
/home/sanchis     => résultat écrit par pwd sur sa sortie standard
$ repert=$(pwd)   => la chaîne /home/sanchis remplace la chaîne $(pwd)
$
$ echo mon repertoire est $repert
mon repertoire est /home/sanchis
$

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 : option non valable
set : utilisation : set [-abefhkmnptuvxBCHP] [-o nom-option] [--] [arg ...]
$ ls -l .bashrc
-rw-r--r-- 1 sanchis sanchis 3525  1  janv.  17:03  .bashrc
$

Le premier mot issu de la substitution commence par un caractère tiret : la commande interne set l'interprète comme une suite d'options, ce qui provoque une erreur. Pour résoudre ce type de problème, on double le caractère tiret [cf. Chapitre 2, Substitution de paramètres, §2.1].

$ set -- $(ls -l .bashrc)
$
$ echo $1
-rw-r--r—
$

Plusieurs commandes peuvent être présentes entre les parenthèses.

$ pwd ; whoami
/home/sanchis
sanchis
$
$ set $(pwd ; whoami)
$
$ echo $2: $1
sanchis: /home/sanchis
$

Les substitutions de commandes peuvent être imbriquées.

$ ls .local
share
$
$ set $( ls $(pwd)/.local )
$ echo $#  		=> nombre d'entrées visibles du répertoire  .local
1
$

Plusieurs sortes de substitutions (de commandes, de variables) peuvent être présentes dans la même commande.

$ read rep
.local
$ set  $( ls  $( pwd )/$rep )	    => substitutions de deux commandes et d'une variable
$			
$ echo $1
share
$

La substitution de commande est utile pour capter les résultats écrits par un fichier shell lors de son exécution.

$ cat jour
#!/bin/bash
#       @(#)    jour

set $(date)
echo $2
$
$ jour		=> le fichier shell jour affiche le jour courant du mois
06
$
$ resultat=$(jour)		=> la variable résultat contient la chaîne 06
$

En utilisant ce mécanisme, un processus père peut récupérer les modifications locales effectuées par un processus fils sur son propre environnement [cf. Chapitre 2, Substitution de paramètres, §1.3].

$ cat modifLOGNAME
#!/bin/bash

LOGNAME=Eric	# modification de la variable d’environnement	
echo $LOGNAME
$

Le fichier shell modifLOGNAME modifie et affiche la nouvelle valeur de la variable d’environnement LOGNAME avant de se terminer.

$ echo $LOGNAME
sanchis				=> valeur initiale de la variable d’environnement
$ 
$ LOGNAME=$(modifLOGNAME)	=> capture de la nouvelle valeur
$ 
$ echo $LOGNAME
Eric				=> la variable d’environnement a été modifiée
$

Exécutée par un processus fils, la modification apportée par modifLOGNAME sur son propre environnement est transmise au processus père (l’interpréteur bash) via :

  • l’affichage de la nouvelle valeur (côté fils)

  • la substitution de commande (côté père).