Expansion de la ligne de commande

Mise à jour : Debian 11.2 - Bullseye

Référence :

Sommaire :

1 - Principe

#    Commentaire
| Filtre
; Séquences de commande
|| Ou conditionnel
&& Et conditionnel
& Exécution en arrière-plan

2 - Séparation en mots

Cette première phase consiste à déterminer, avant les expansions éventuelles, les mots constituant la commande

2.1 - Définitions

2.2 - Cas d'une chaîne de caractère simple

$ echo un deux trois
#!/usr/bin/env bash
# Affichage des mots de la ligne de commande

echo "Nombre de mots passés en argument : $#"


# Affichage des arguments
i=1
while (($i<=$#));do

echo "Mot $i ###${!i}###"
i=$((++i))
done
$ ./mots un     deux        trois
Nombre de mots passés en argument : 3
Mot 1 ###un###
Mot 2 ###deux###
Mot 3 ###trois###

Note : Le nom du script n'est pas pris en compte dans le décompte et l'affichage des mots

2.3 - Inclusion de séparateurs dans un mot

2.3.1 Utilisation de l'antislash

$ ./mots un\ deux\ trois
Nombre de mots passés en argument : 1
Mot 1 ###un deux trois###

2.3.2 Utilisation des guillemets et des apostrophes

./mots "un   deux trois" quatre
Nombre de mots passés en argument : 2
Mot 1 ###un deux trois###
Mot 2 ###quatre###
$ ./mots 'un   deux trois' quatre
Nombre de mots passés en argument : 2
Mot 1 ###un deux trois###
Mot 2 ###quatre###

2.3.3 Séparateurs en début ou fin de mot

Un mot peut commencer ou finir par un ou plusieurs séparateurs, ou ne comprendre que des séparateurs

$ ./mots " ce mot commence et finit par deux espaces  "
Nombre de mots passés en argument : 1
Mot 1 ### ce mot commence et finit par deux espaces ###

$ ./mots "le mot qui suit comprend deux espaces" " "
Nombre de mots passés en argument : 2
Mot 1 ###le mot qui suit comprend deux espaces###
Mot 2 ### ###

2.3.4 Mots vides

$ ./mots "Un mot vide" "" "Entre deux mots"
Nombre de mots passés en argument : 3
Mot 1 ###Un mot vide###
Mot 2 ######
Mot 3 ###Entre deux mots###

2.4 - Inclusion de caractères d'échappement

La solution varie selon que le caractère d'échappement à inclure est dans un mot "échappé" ou non avec des apostrophes ou guillemets

2.4.1 Inclusion d'un antislash

$ echo anti\\slash
anti\slash
$ echo "anti\slash" 'anti\slash'
anti\slash anti\slash

2.4.2 Inclusion d'une apostrophe

$ echo l\'apostrophe
l'apostrophe
$ echo "l'apostrophe"
l'apostrophe
$ echo 'l'\''apostrophe'
l'apostrophe

2.4.3 Insertion d'un guillemet

$ echo un\"guillemet
un"guillemet
$ echo "un\"guillemet"
un"guillemet
$ echo 'un"guillemet'
un"guillemet

3 - Accolades {} : Énumérations

$ echo pre-{un,deux,trois}-post
pre-un-post pre-deux-post pre-trois-post
$ echo pre-{10..13}-post
pre-10-post pre-11-post pre-12-post pre-13-post
$ echo pre-{r..v}-post
pre-r-post pre-s-post pre-t-post pre-u-post pre-v-post
$ echo {p,q,z}xxx{1..3}
pxxx1 pxxx2 pxxx3 qxxx1 qxxx2 qxxx3 zxxx1 zxxx2 zxxx3

4 - Tilde ~ : Répertoires

~ : Répertoire de login ($HOME)

~+ : Répertoire courant ($PWD)

~- : Répertoire précédent ($OLDPWD)

$ cd ~/Téléchargement
$ cd ~/Bureau

$ echo ~ # ~ est le répertoire de login
/home/user

$ echo ~+ # ~+ est le répertoire courant
/home/user/Bureau

$ echo ~- # ~- est le répertoire précédent
/home/user/Téléchargement

5 - Dollard $ : Expansion de paramètre

5.1 - Expansions directe et indirecte

$ exemple='Ceci est une chaîne de caractères'

$ echo $exemple
ceci est une chaîne de caractères
$ i="HOME"

$ echo $i HOME
$ echo ${!i} /home/philippe
$ set un deux trois quatre

$ echo le nombre de paramètres est $#
le nombre de paramètres est 4

$ echo le paramètre 1 est $1
le paramètre 1 est un

$ echo le paramètre 4 est $4
le paramètre 4 est quatre

$ echo les paramètres sont $@
les paramètres sont un deux trois quatre
$ date
dimanche 13 août 2017, 22:59:26 (UTC+0200)

$ echo le pid de la dernière commande est $$
le pid de la dernière commande est 2167

$ echo le code de sortie de la dernière commande est $?
le code de sortie de la dernière commande est 0

5.2 - Conversion

On prend pour exemple la variable

$ var=abcde1234ABCDE
$ echo ${var^}
Abcde1234ABCDE
$ echo ${var^^}
ABCDE1234ABCDE
$ echo ${var^^[bc]}
aBCde1234ABCDE
$ echo ${var,}
abcde1234ABCDE
$ echo ${var,,}
abcde1234abcde
$ echo ${var,,[BC]}
abcde1234AbcDE

5.3 - Suppression d'une partie du motif

$ echo ${var#123}
4ABCD1234
$ echo ${var#*23}
4ABCD1234
$ echo ${var##*23}
4
$ echo ${var%34}
1234ABCD12
$ echo ${var%23*}1234ABCD1
$ echo ${var%%23*}1

5.4 - Remplacement de motif

$ i=1234ABCD1234
$ echo ${var/23/--bonjour--}
1--bonjour--4ABCD1234
$ echo ${var//23/--bonjour--}
1--bonjour--4ABCD1--bonjour--4

5.5 - Expansion sous-chaîne

$ echo ${var:4}
e1234ABCDE
$ echo ${var:4:3}
e12
$ echo ${var: 4: -3}e1234AB
$ echo ${var: -4}
BCDE
$ echo ${var: -4:3}
BCD
$ echo ${var: -8: -3}
234AB

5.6 - Conversion de codes

$ echo $'\x63\x6f\x6e\x76\x65\x72\x73\x69\x6f\x6e'
conversion
$ echo $'\x269\x370'
&970
$ echo -n $'\t\n' |hexdump
00000000 09 0a

6 - Dollard $ : Expansion arithmétique

$((calcul)) : Le calcul arithmétique est effectué

$ echo $((1+2))
3

$ echo $((1+2**3))
9

$ echo $((((1+2**3))/7))
1

# Reste de la division
echo $((10%3))
1
$ for i in {1,2,3}; do echo $((++i)); done
2
3
4
$ for i in {1,2,3}; do echo $((i++)); done
1
2
3
$ var=10

$ echo $((- $var))
-10
$ var=-10

$echo $(( + $var ))
-10
# Comparaison var1 et var2 : 

$ echo $(( 10 == 10 ))
1 # x est égal à y : vrai

$ echo $(( 10 != 10 ))
0 # x est différent de y : faux

$ echo $(( 10 >= 10 ))
1 # 10 est supérieur ou égal à 10 : vrai

$ echo $(( 10 > 10 ))
0 # 10 est supérieur à 10 : faux

7 - Dollard $ : Substitution de commande

$ echo "Nous sommes le $(date)"
Nous sommes le ven. 21 janv. 2022 12:27:53 CET
$ version=$(uname -r)

$ echo $version
5.15.0-0.bpo.2-amd64

8 - Découpe des mots

Références :

8.1 - Principe

$ ./mots '$(date)'
Nombre de mots passés en argument : 1
Mot 1 ###$(date)###
$ ./mots "$(date)"
Nombre de mots passés en argument : 1
Mot 1 ###lun. 24 janv. 2022 17:04:31 CET###
$ ./mots $(date)
Nombre de mots passés en argument : 6
Mot 1 ###lun.###
Mot 2 ###24###
Mot 3 ###janv.###
Mot 4 ###2022###
Mot 5 ###17:02:14###
Mot 6 ###CET###

8.2 - Caractères séparateurs

8.2.1 Caractères par défaut

$ echo -n "$IFS" |hexdump -C
00000000 20 09 0a | ..|
$ var="La variable contient       plusieurs espaces"

$ ./mots $var
Nombre de mots passés en argument : 5
Mot 1 ###La###
Mot 2 ###variable###
Mot 3 ###contient###
Mot 4 ###plusieurs###
Mot 5 ###espaces###

8.2.2 Caractères personnalisés

$ IFS="$IFS:"

$ echo -n "$IFS" |hexdump -C
00000000 20 09 0a 3a | ..:|
$ var="colonne1:colonne2:colonne3"

$ ./mots $var
Nombre de mots passés en argument : 3
Mot 1 ###colonne1###
Mot 2 ###colonne2###
Mot 3 ###colonne3###
$ var="colonne1 :   colonne2 :   colonne3"

$ ./mots $var
Nombre de mots passés en argument : 3
Mot 1 ###colonne1###
Mot 2 ###colonne2###
Mot 3 ###colonne3###
$ var="colonne1::colonne2 :: colonne3"

$ ./mots $var
Nombre de mots passés en argument : 5
Mot 1 ###colonne1###
Mot 2 ######
Mot 3 ###colonne2###
Mot 4 ######
Mot 5 ###colonne3###

9 - Caractères spéciaux (wildcards) dans les noms de fichier : *,?, [ ]

$ touch photo1 photo2 photo3 photoa photob photoc

9.1 - Remplacement de n'importe quel caractère

$ ls p*cphotoc
$ ls ph?tocphotoc

9.2 - Remplacement par tout caractère d'une classe de caractère

[[:alnum:]]  [[:alpha:]]     [[:digit:]]     [[:xdigit:]]

[[:lower:]] [[:upper:]]

[[:blank:]] [[:space:]]

[[:punct:]] [[:graph:]] [[:print:]]
[![:blank:]]

9.3 - Remplacement par tout caractère d'une liste de caractères

$ ls photo[1ac]
photo1 photoa photoc
$ ls photo[1-3]
photo1 photo2 photo3

$ ls photo[a-c]
photoa photob photoc
$ ls photo[^1ac]
photo2 photo3 photob

10 - Substitution de process

Les caractères > et < - Substitution de process : Voir Redirections & enchaînements