Exploration des Mécanismes d'Extension en Shell Scripting

Extension par Guillemets (Brace Expansion)

Cette fonctionnalité permet de générer des séquences de chaînes de caractères. Elle ne tolère pas l'utilisation de guillemets autour des éléments de la séquence.


$ echo {debut,milieu,fin}
debut milieu fin

$ echo {a..e}
a b c d e

$ echo {10..20..3}
10 13 16 19

$ echo pref{ixe1,ixe2}suffix
prefixe1suffix prefixe2suffix

Extension par Tilde (Tilde Expansion)

Le tilde (~) représente le répertoire personnel de l'utilisateur courant. Il est également possible de spécifier un nom d'utilisateur valide après le tilde pour accéder à son répertoire personnel.


# Affichage du répertoire personnel de l'utilisateur courant
$ echo ~
/home/utilisateur

# Affichage du répertoire personnel d'un autre utilisateur (si valide)
$ echo ~autre_utilisateur
/home/autre_utilisateur

~+ désigne le répertoire de travail courant, tandis que ~- fait référence au répertoire de travail précédent.

Substitution de Paramètres et Variables

L'utilisation de $ permet de substituer la valeur d'une varible. Encapsuler la variable dans des accolades {} est utile pour éviter toute ambiguïté avec les caractères adjacents. Les variables positionnelles de plus d'un chiffre nécessitent obligatoirement des accolades, par exemple ${10}.

L'ajout d'un point d'exclamation ! à l'intérieur des accolades (${!variable}) permet une référence indirecte à la valeur de la variable, et ce, sur une seule profondeur.

Cette substitution peut également servir à tester l'existence ou la vacuité d'une variable et à lui assigner une valeur par défaut si nécessaire.


$ nom_animal="chats"
$ echo ${nom_animal:-"chiens"}
chats

$ echo $nom_animal

$ nom_animal2="oiseaux"
$ echo ${nom_animal2:="perroquets"}
oiseaux

$ echo $nom_animal2
perroquets

$ unknown_var='erreur'
$ echo ${non_definie:?'Erreur: Variable non définie'}
bash: non_definie: Erreur: Variable non définie

$ var_existante=valeur
$ echo ${var_existante:+"present"}
present
$ echo $var_existante
valeur

Manipulation de Chaînes de Caractères

Des opérations de découpage et de suppression de préfixes/suffixes sont possibles.


$ chaine="Le grand arbre, il était couvert de mouchoirs colorés."

# Extraire une sous-chaîne à partir de l'index 5 (le 5ème caractère est à l'index 4)
$ echo ${chaine:5}
grand arbre, il était couvert de mouchoirs colorés.

# Extraire une sous-chaîne de 10 caractères à partir de l'index 10
$ echo ${chaine:10:10}
arbre, il

# Supprimer le préfixe "Le "
$ echo ${chaine#Le }
grand arbre, il était couvert de mouchoirs colorés.

# Supprimer le préfixe "Le grand "
$ echo ${chaine#Le grand }
arbre, il était couvert de mouchoirs colorés.

# Supprimer le plus court préfixe correspondant à "grand "
$ echo ${chaine#*grand }
arbre, il était couvert de mouchoirs colorés.

# Supprimer le plus long préfixe correspondant à "grand "
$ echo ${chaine##*grand }
arbre, il était couvert de mouchoirs colorés.

# Supprimer le suffixe le plus court correspondant à " colorés."
$ echo ${chaine% colorés.}
Le grand arbre, il était couvert de mouchoirs

# Supprimer le suffixe le plus long correspondant à " colorés."
$ echo ${chaine%% colorés.}
Le grand arbre, il était couvert de mouchoirs

# Supprimer le plus court suffixe commençant par "colorés"
$ echo ${chaine%colorés*}
Le grand arbre, il était couvert de mouchoirs

# Supprimer le plus long suffixe commençant par "colorés"
$ echo ${chaine%%colorés*}
Le grand arbre, il était couvert de mouchoirs

Opérations sur les Tableaux

Ces extensions s'appliquent également aux éléments de tableaux.


$ outils=("voiture" "hélicoptère" "avion" "train")
$ echo ${outils[0]}
voiture

# Supprimer le préfixe "v" du premier élément
$ echo ${outils[0]#v}
oiture

Substitution de Commande

La substitution de commande permet d'exécuter une commande et d'utiliser sa sortie comme argument ou comme valeur. Les formats $(commande) et commande sont disponibles. Le format $() est préférable car il supporte la substitution imbriquée.


$ echo "Nombre d'utilisateurs connectés : $(who | wc -l)"

Substitution Arithmétique

Elle permet d'évaluer des expressions arithmétiques. Les syntaxes $((expression)) et $[expression] sont supportées, et les substitutions peuvent être imbriquées.


$ echo $((var_compteur++)) # Incrémente et retourne la valeur avant incrémentation
$ echo $((2**5))          # Puissance : 2 élevé à la puissance 5
$ echo $((30/6))          # Division
$ echo $((5 == 5))        # Comparaison : égalité (retourne 1 pour vrai, 0 pour faux)
$ echo $((7 != 8))        # Comparaison : différence (retourne 1 pour vrai, 0 pour faux)

Substitution de Processus (Process Substitution)

Contrairement à la substitution de commande qui retourne une chaîne, la substitution de processus transmet la sortie d'un processus à un autre via un tube nommé (FIFO).

La syntaxe est <(commande) ou >(commande). Le système crée un descripteur de fichier dans /dev/fd/ pour faciliter ce transfert.


# Utilisation avec un tube nommé classique
$ who | wc -l
1

# Utilisation avec la substitution de processus
$ wc -l <(who)
1 /dev/fd/63

# Le descripteur de fichier est temporaire et disparaît après usage
$ ls /dev/fd/63
ls: impossible d'accéder à /dev/fd/63: Aucun fichier ou dossier de ce type

L'exemple who | wc -l compte le nombre de lignes retournées par who. Avec la substitution de processus, <(who) redirige la sortie de who vers un descripteur de fichier (ex: /dev/fd/63) qui est ensuite utilisé comme entrée par wc -l. Le résultat indique que le descripteur contient 1 ligne.

Pour combiner des informations de différents fichiers :


# Extraire les noms d'utilisateur (1ère colonne) et répertoires personnels (6ème colonne) de /etc/passwd
# Extraire les informations de mot de passe (2ème colonne) de /etc/shadow
# Concaténer les résultats ligne par ligne avec paste
$ paste <(cut -d: -f1,6 /etc/passwd) <(cut -d: -f2 /etc/shadow)

Gestion des fichiers et filtrage via la substitution de processus :


$ touch {a,b,c}.sh
$ touch {fichier1,fichier2,fichier3}.conf
$ ls | tee >(grep sh$ > scripts.log) >(grep conf$ > configs.log)
a.sh
b.sh
c.sh
fichier1.conf
fichier2.conf
fichier3.conf
scripts.log
configs.log

Découpage en Mots (Word Splitting)

Le shell découpe les chaînes de caractères en "mots" en se basant sur le séparateur défini par la variable d'environnement IFS (Internal Field Separator). Par défaut, IFS contient l'espace, la tabulation et le saut de ligne.

Extension de Chemin (Pathname Expansion / Globbing)

Sauf si désactivée par set -f, le shell interprète les caractères spéciaux comme *, ?, et [...] dans les chemins et noms de fichiers pour effectuer des correspondances de motifs (globbing). L'option nocaseglob (activable avec shopt -s nocaseglob) permet d'ignorer la casse lors de la correspondance. L'option extglob (activable avec shopt -s extglob) active des fonctionnalités de correspondance étendues.


# Obtenir le nom du répertoire parent
$ dirname /home/utilisateur/documents/rapport.txt
/home/utilisateur/documents

# Obtenir le nom de fichier seul
$ basename /home/utilisateur/documents/rapport.txt
rapport.txt

Étiquettes: Shell scripting bash expansion substitution

Publié le 24 juin à 02h06