Support N°4 : Le shell et les commandes Gnu (suite)

Transcription

Support N°4 : Le shell et les commandes Gnu (suite)
Le système d'exploitation Debian/Gnu Linux
C. HEMDANI
Support N°4 :
Le shell et les commandes Gnu (suite)
Table des matières
1 Les processus
1
1.1
Dénition et environnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2
États d'un processus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.3
Lancement en tâche de fond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.4
Backgroung, foreground, jobs
2
1.5
Liste des processus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.6
Les signaux
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.7
nohup
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.8
nice et renice
1.9
time
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2 Alias, groupement et liaison de commandes
5
2.1
Alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2
Groupement de commandes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.3
Liaison et exécution conditionnelle
6
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 Les variables
5
6
3.1
Nomenclature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3.2
Déclaration et aectation
6
3.3
Accès et achage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3.4
Suppression et protection
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3.5
Export . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3.6
Accolades
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.7
Variables système . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.8
Variables spéciales
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.9
Longueur d'une chaîne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.10 Tableaux et champs
3.11 Variables typées
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
4 Conguration de bash
4.1
10
Fichiers de conguration
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1
Shell de connexion
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
4.1.2
Shell simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
4.1.3
Mode non interactif
11
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5 Structure et exécution d'un script
5.1
10
11
Arguments d'un script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
5.1.1
Paramètres de position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
5.1.2
Redénition des paramètres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
5.1.3
Réorganisation des paramètres
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
5.1.4
Sortie d'un script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
5.2
Environnement du processus
5.3
Substitution de commande
5.4
Tests de conditions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.1
Tests sur une chaîne
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.2
Tests sur les valeurs numériques
5.4.3
Tests sur les chiers
14
14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
5.4.4
Tests combinés par des critères ET, OU et NON
5.4.5
Syntaxe allégée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
5.5
if ... then ... else ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5.6
Choix multiples : case
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5.7
Saisie de l'utilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
5.8
Les boucles
5.9
. . . . . . . . . . . . . . . . . . . . . .
15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
5.8.1
Boucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
5.8.2
Boucle while
19
5.8.3
Boucle until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
5.8.4
true et false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
5.8.5
break et continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les fonctions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.10 Calculs et expressions
19
20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
5.10.1 expr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
5.10.2 Calculs avec bash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
5.11 Une variable dans une autre variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
5.12 Traitement des signaux
22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Le système d'exploitation Debian/Gnu Linux
C. HEMDANI
Support N°4 :
Le shell et les commandes Gnu (suite)
1 Les processus
1.1 Dénition et environnement
Un processus représente à la fois un programme en cours d'exécution et tout son environnement d'exécution
(mémoire, état, identication, propriétaire, père...). Voici une liste des données d'identication d'un processus :
Un numéro de processus unique PID (Process
ID )
: chaque processus Unix est numéroté an de
pouvoir être diérencié des autres. Le premier processus lancé par le système a le
processus appelé
systemd (init
dans les anciennes versions). On utilise le
un processus. Lancer 10 fois le même programme produit 10
PID
PID
PID 1 et il s'agit d'un
quand on travaille avec
diérents.
Un numéro de processus parent PPID (Parent Process ID ) : chaque processus peut lui-même lancer
d'autres processus, des processus enfants (child
le
PID
process ).
Chaque enfant reçoit parmi les informations,
du processus père qui l'a lancé. Tous les processus ont un
PPID
sauf le processus 0 qui est un
pseudo-processus représentant le démarrage du système et qui sera l'ancêtre de tous les processus.
Un numéro d'utilisateur et un numéro de groupe
: ils correspondent à l'UID et au
GID
de
l'utilisateur qui a lancé le processus. C'est nécessaire pour que le système sache si le processus a le droit
d'accéder à certaines ressources ou non. Les processus enfants héritent de ces informations.
Durée de traitement et priorité : la durée de traitement correspond au temps d'exécution écoulé
depuis le dernier réveil du processus. Dans un environnement multitâche, le temps d'exécution est
partagé entre les divers processus, et tous ne possèdent pas la même priorité. Les processus de plus
haute priorité sont traités en premier. Lorsqu'un processus est inactif, sa priorité augmente an d'avoir
une chance d'être exécuté. Lorsqu'il est actif, sa priorité baisse an de laisser sa place à un autre. C'est
l'ordonnanceur de tâches du système qui gère les priorités et les temps d'exécution.
Répertoire de travail actif
: à son lancement, le répertoire courant (celui depuis lequel le processus
a été lancé) est transmis au processus. C'est ce répertoire qui servira de base pour les chemins relatifs.
Fichiers ouverts
: table des descripteurs des chiers ouverts. Par défaut, au début, seuls trois sont
présents : 0, 1 et 2 (les canaux standards). À chaque ouverture de chier ou de nouveau canal, la table
se remplit. À la fermeture du processus, les descripteurs sont fermés.
Autres informations : comme la taille de la mémoire allouée, la date de lancement du processus, le
terminal d'attachement, l'état du processus, ...
1.2 États d'un processus
Durant sa vie (temps entre le lancement et la sortie), un processus peut passer par divers états :
exécution en mode utilisateur (user
exécution en mode noyau (kernel
en attente d'E/S (waiting ),
mode ),
mode ),
endormi (sleeping ),
prêt à l'exécution (runnable ),
endormi dans le swap (mémoire
virtuelle ),
nouveau processus,
n de processus (zombie ).
1.3 Lancement en tâche de fond
Le shell peut autoriser la saisie d'une nouvelle commande sans attendre la n de l'exécution de la commande
précédente. Pour cela il sut de saisir, après avoir tapé la commande, le caractère
la commande lancée fonctionneront en parallèle.
$ ls -R / > ls . txt &
[1] 2835
$
[1] Done
1
&.
Dans ce cas, le shell et
Juste après la saisie, un nombre apparaît (2835 dans l'exemple), il est à retenir car il s'agit du
nouveau processus lancé. Après une autre saisie, une ligne
valeur
[1]
Done
PID
du
indique que le traitement est terminé. La
est propre au shell particulier (bash).
Remarque 1
Le processus lancé en tâche de fond
ne devrait pas attendre de saisie au risque de confusion entre cette commande et le shell lui-même,
et
ne devrait pas acher de résultats sur l'écran au risque d'avoir des achages en conit avec celui
du shell (par exemple, l'apparition d'une ligne en milieu de saisie).
Quand on quitte le shell, on quitte aussi tous ses ls : c'est pour cela qu'il ne faut pas quitter le shell
pendant un traitement important.
1.4 Backgroung, foreground, jobs
On peut récupérer la main sous le shell si on a lancé un processus au premier plan. On peut le stopper
temporairement (le suspendre) en tapant
$ sleep 100
^Z
[1]+ Stopped
[Ctrl] Z
:
sleep 100
Le processus est stoppé : son exécution est suspendue jusqu'à ce qu'on le replace au premier plan avec la
commande
fg (foreground )
:
$ fg sleep 100
sleep 100
Quand on lance une commande, le premier nombre entre crochets est le numéro de job. On peut obtenir
la liste des jobs avec la commande
jobs.
$ sleep 40&
[1] 2968
$ sleep 60&
[2] 2969
$ jobs
[1] - Running
[2]+ Running
$ fg 2
sleep 60
^Z
[2]+ Stopped
$ bg 2
[2]+ sleep 60 &
Les commandes
commande
bg
sleep 40 &
sleep 60 &
sleep 60
bg
et
fg
permettent d'agir sur ces jobs en prenant comme paramètre leur numéros. La
est exécutée sur un job stoppé pour le relancer en arrière-plan (background ).
1.5 Liste des processus
La commande
ps (process status ) permet d'avoir des informations sur les processus en cours. Lancée seule,
elle n'ache que les processus en cours lancés par l'utilisateur et depuis la console actuelle.
$ ps
PID TTY
2916 pts /2
3120 pts /2
TIME CMD
00:00:00 bash
00:00:00 ps
Pour avoir plus d'informations, on utilise le paramètre
$ ps -f
UID
etudiant
etudiant
PID PPID C STIME TTY
2916 2527 0 14:19 pts /2
3132 2916 0 14:34 pts /2
Le paramètre
-e
-f.
TIME CMD
00:00:00 bash
00:00:00 ps -f
donne des informations sur tous les processus en cours.
2
$ ps -e
PID TTY
1 ?
2 ?
3 ?
...
TIME
00:00:00
00:00:00
00:00:00
Le paramètre
paramètre
-g
-u
permet de préciser une liste d'un ou plusieurs utilisateurs séparés par une virgule. Le
eectue la même chose mais pour les groupes,
$ ps -u root
PID TTY
1 ?
2 ?
3 ?
...
TIME
00:00:00
00:00:00
00:00:00
-l
Enn le paramètre
$
F
0
0
ps -l
S
UID
S 1000
R 1000
CMD
systemd
kthreadd
ksoftirqd /0
PID
2916
3179
-t
pour les terminaux et
-p
pour des
PID
précis.
CMD
systemd
kthreadd
ksoftirqd /0
propose plus d'informations techniques.
PPID
2527
2916
C PRI
0 80
0 80
NI ADDR SZ WCHAN
0 - 1728 0 953 -
TTY
pts /2
pts /2
TIME CMD
00:00:00 bash
00:00:00 ps
Le tableau suivant dénit quelque colonnes.
Colonne
Dénition
UID
PID
PPID
C
STIME
TTY
TIME
CMD
S
PRI
NI
User ID, numéro de l'utilisateur.
Process ID, numéro du processus.
Parent Process ID, numéro du processus père.
Facteur de priorité, plus la valeur est grande plus la priorité est élevée.
Heure de lancement du processus.
Nom du terminal depuis lequel le processus a été lancé.
Durée de traitement du processus.
Commande exécutée.
État du processus :
S
(sleeping),
R
(running),
Z
(zombie).
Priorité du processus.
Nice, incrément pour l'ordonnanceur.
1.6 Les signaux
Lorsqu'un processus tourne en tâche de fond, il ne peut pas être arrêté par une quelconque combinaison
de touches. Il peut être nécessaire de lui envoyer des signaux auxquels il pourra éventuellement réagir. Pour
cela, il faut employer la commande
kill.
Contrairement à ce que son nom semble indiquer, le rôle de cette commande n'est pas forcément de détruire
ou de terminer un processus, mais d'envoyer des signaux aux processus.
kill [ - l ] - signal PID1 [ PID2 ...]
Le signal est l'un des moyens de communication entre les processus. Lorsqu'on envoie un signal à un
processus, celui-ci doit l'intercepter et réagir en conséquence. Certains signaux peuvent être ignorés, d'autres
non. Ils sont numérotés et nommés. L'option
$ kill -l
1) SIGHUP
6) SIGABRT
...
63) SIGRTMAX -1
2) SIGINT
7) SIGBUS
-l
permet d'obtenir la liste des signaux.
3) SIGQUIT
8) SIGFPE
4) SIGILL
9) SIGKILL
5) SIGTRAP
10) SIGUSR1
64) SIGRTMAX
Les rôles des signaux les plus utilisés sont donnés dans le tableau suivant.
Signal
1)
2)
3)
9)
15)
SIGHUP
SIGINT
SIGQUIT
SIGKILL
SIGTERM
Rôle
Hang Up, est envoyé par le père à tous ses enfants lorsqu'il se termine.
Intérruption du processus ([CTRL]
C).
Intérruption du processus avec génération d'un Core Dump (chier de débogage).
Signal ne pouvant être ignoré et qui force le processus à nir 'brutalement'.
Demande au processus de se terminer normalement.
3
Par défaut, la commande
kill
envoie le signal
$ sleep 100&
[1] 3379
$ kill 3379
$
[1]+ Complété
$ sleep 100&
[1] 3388
$ kill -9 3388
$
[1]+ Processus arrêté
SIGTERM.
sleep 100
sleep 100
1.7 nohup
Quand le shell est quitté (exit,
[Ctrl] D,
...), le signal
1 (SIGHUP)
est envoyé aux enfants pour qu'ils se
terminent aussi. Lorsqu'un traitement long est lancé en tâche de fond et que l'utilisateur veut quitter le shell,
ce traitement sera alors arrêté et il faudra tout recommencer. Le moyen d'éviter cela est de lancer le processus
avec la commande
nohup.
Dans ce cas, le processus lancé ne réagira plus au signal
SIGHUP,
pourra être quitté, la commande continuera son exécution.
Par défaut les canaux de sortie et d'erreur standards sont redirigés vers un chier
redirection est explicitement précisée.
et donc le shell
nohup.out,
sauf si la
$ nohup ls -R / &
[1] 3430
$ nohup : les entrées sont ignorées et la sortie est ajoutée à nohup . out
SIGCHLD à son père. Sauf cas prévu (le père se détache du ls),
SIGHUP. Si le père se termine avant ses
ls, ceux-ci deviennent des zombis : le signal SIGCHLD n'est pas reçu... Le processus ls est bien terminé, il est
Quand un ls se termine, il envoie le signal
le père doit obtenir autant de
SIGCHLD
qu'il a eu de ls ou émis de
mort, il ne consomme aucune ressource. Il ne peut donc être tué (puisqu'il est mort) mais continue à occuper
une entrée dans la table des processus.
1.8 nice et renice
La commande
nice
permet de lancer une commande avec une priorité plus faible, an de permettre éven-
tuellement à d'autres processus de tourner plus rapidement.
nice [ - valeur ] commande [ arguments ]
Une valeur positive causera une baisse de priorité et une valeur négative l'augmentera (si autorisé). La
valeur doit être comprise entre
$ nice -10
[1] 3488
$ ps -l
F S
UID
0 S 1000
0 R 1000
0 R 1000
PID,
et
19.
Plus la valeur est élevée, plus le traitement est ralenti.
ls -R / > liste 2 >/ dev / null &
PID
2916
3488
3489
La commande
d'un
-20
PPID C PRI
2527 0 80
2916 83 90
2916 0 80
renice
NI
0
10
0
ADDR SZ
- 1767
- 1548
953
fonctionne un peu comme
nice
WCHAN
-
TTY
pts /2
pts /2
pts /2
TIME
00:00:00
00:00:02
00:00:00
CMD
bash
ls
ps
mais elle permet de modier la priorité en fonction
d'un utilisateur ou d'un groupe de processus.
renice [ - n ] priorité [[ - p ] PID ...] [[ - g ] PGID ...] [[ - u ] utilisateur ...]
0
La priorité doit être comprise entre
et
19
-20
et
19.
L'utilisateur standard ne peut utiliser que les valeurs entre
permettant de baisser la priorité.
Les paramètres sont interprétés comme des identiants de processus (PID), des identiants d'un groupe de
processus (PGID) ou des noms d'utilisateurs. A titre d'exemple, la commande
# renice +5 3495 -u etudiant root -p 437
changera la priorité des processus d'identiants
utilisateurs
etudiant
et
root.
3495
et
4
437,
et celles de tous les processus appartenant aux
1.9 time
La commande
time
mesure les durées d'exécution d'une commande, idéale pour connaître les temps de
traitement. Elle retourne trois valeurs :
real : durée totale d'exécution de la commande,
user : durée du temps CPU nécessaire pour exécuter le programme,
sys : durée du temps CPU nécessaire pour exécuter les appels système eectués au sein du programme.
$ time ls -R ~ > liste
real
0 m0 .031 s
user
0 m0 .020 s
sys
0 m0 .012 s
2 Alias, groupement et liaison de commandes
2.1 Alias
Un alias est un raccourci d'une commande avec d'éventuels paramètres. Il se dénit avec la commande
alias.
Utilisée seule, elle liste les alias disponibles.
$ alias
alias ..= ' cd .. '
alias cd ..= ' cd .. '
alias l = ' ls -alF '
alias la = ' ls -la '
alias ll = ' ls -l '
alias rm = ' rm -i '
On peut créer ses propres alias comme par la commande suivante :
$ alias deltree = ' rm -rf '
2.2 Groupement de commandes
On peut chaîner des commandes avec le caractère point-virgule ';' pour les faire exécuter en séquentiel.
$ uname -a ; pwd ; ls -l
uname -a
est d'abord exécutée, puis
pwd
et en n
ls -l.
Dans l'exemple suivant :
$ uname -a ; pwd ; ls -l > resultat . txt &
seule la dernière commande est exécutée en tâche de fond et seul son résultat est redirigé dans le chier
resultat.txt. Comment faire alors pour que chacune d'elle redirige sa sortie vers resultat.txt et s'exécute
en tâche de fond ?
Une solution serait :
$ uname -a > resultat . txt & pwd >> resultat . txt & ls -l >> resultat . txt &
[1] 3097
[2] 3098
[3] 3099
Cependant, trois processus sont lancés en tâches de fond et non pas un seul. De plus, si les commandes
sont lancées séquentiellement, elles tournent toutes en parallèle et c'est la première nie qui écrira en premier
dans le chier.
La solution consiste en l'utilisation des parenthèses.
$ ( uname -a ; pwd ; ls -l ) > resultat . txt &
[1] 3112
Un seul processus est lancé en tache de fond. Toutes les commandes placées entre les parenthèses sont
lancées par un sous-shell unique, qui va exécuter séquentiellement les commandes indiquées. Ainsi, la redirection
concerne l'ensemble des commandes et rien n'empêche de lancer ce sous-shell en arrière-plan.
Une seconde possibilité est l'utilisation des accolades
{ ... }. Dans ce cas, aucun sous-shell n'est exécuté,
et si une commande interne (cd ou autre) est exécutée, elle concerne le shell actif.
5
$ { uname -a ; pwd ; ls -l ; } > resultat . txt
Notons qu'il faut laisser un espace entre l'accolade ouvrante et la première commande, et qu'il faut placer
un ';' entre la dernière commande et l'accolade fermante.
2.3 Liaison et exécution conditionnelle
En plus du chaînage classique, les commandes peuvent être liées et exécutées de façon conditionnelle. La
condition d'exécution d'une commande est la réussite ou non de la précédente. Une fois exécutée, chaque
commande renvoie un code de retour, généralement
peut récupérer cette valeur par la variable
Les opérateurs
&&
et
||
$?.
0
si tout s'est bien passé,
1
ou
2
en cas d'erreur. Le shell
permettent d'eectuer une exécution conditionnelle.
commande1 && commande2
commande1 || commande2
La commande située après
La commande située après
||
&& sera exécutée uniquement si la commande précédente a retourné 0 (réussite).
ne sera exécutée que si la commande précédente a retourné autre chose que 0.
$ cat document
Ce document présente le système
d ' exploitation Debian Gnu / Linux .
$ grep " Debian " document > / dev / null && echo " Trouvé " || echo " Introuvable "
Trouvé
$ grep " RedHat " document > / dev / null && echo " Trouvé " || echo " Introuvable "
Introuvable
3 Les variables
On distingue trois types de variables : utilisateur, système et spéciales. Le principe est de pouvoir aecter
un contenu à un nom de variable, généralement une chaîne de caractères ou des valeurs numériques.
3.1 Nomenclature
Un nom de variable a le même modèle que les identicateurs du langage
C. On convient, généralement, que
les variables utilisateur soient en minuscules pour les diérencier des variables système (en majuscules).
3.2 Déclaration et aectation
Une variable est déclarée dès qu'une valeur lui est aectée. L'aectation est réalisée avec le symbole
=, sans
espace avant ou après le signe.
var=Bonjour
3.3 Accès et achage
$ devant le nom de la variable. Quand le shell
$, il tente d'interpréter le mot suivant comme étant une variable. Si elle existe, alors $nom_variable
On accède au contenu d'une variable en plaçant le caractère
rencontre le
est remplacé par son contenu, ou par un texte vide dans le cas contraire. On parle aussi de référencement de
variable.
$ chemin =/ usr / include
$ ls $chemin
...
$ cd $chemin
$ pwd
/ usr / include
$ cd $chemin / linux
$ pwd
/ usr / include / linux
Pour acher la liste des variables, on utilise la commande
variables système, nom et contenu.
6
env.
Elle ache les variables utilisateur et les
$ env
XDG_VTNR =7
MATE_DESKTOP_SESSION_ID = this - is - deprecated
XDG_SESSION_ID =1
SSH_AGENT_PID =1631
GPG_AGENT_INFO =/ run / user /1000/ keyring / gpg :0:1
TERM = xterm
...
Une variable peut contenir des caractères spéciaux, le principal étant l'espace. L'exemple suivant ne fonctionne pas :
$ s = Salut tout le monde
bash : tout : commande introuvable
Pour cela il faut soit verrouiller les caractères spéciaux par un
\,
soit les mettre entre guillemets ou
apostrophes.
$ s = Salut \ tout \ le monde
$ s =" Salut tout le monde "
$ s = ' Salut tout le monde '
# Solution lourde
# Solution correcte
# Solution correcte
La principale diérence entre les guillemets et les apostrophes est l'interprétation des variables et des
substitutions. Précisons aussi que
"
et
'
se verrouillent mutuellement.
$ d = debian
$ u = ubuntu
$ echo " La distribution $u est basée sur $d ."
La distribution ubuntu est basée sur debian .
$ echo ' La distribution $u est basée sur $d . '
La distribution $u est basée sur $d .
$ echo ' La distribution " $u est basée sur $d ". '
La distribution " $u est basée sur $d ".
3.4 Suppression et protection
unset. On protège une variable en écriture et contre sa
readonly. Une variable en lecture seule, même vide, est gée. Il n'existe aucun
On supprime une variable avec la commande
suppression avec la commande
moyen de la replacer en écriture ou de la supprimer, sauf en quittant le shell.
$ d = debian
$ u = ubuntu
$ echo " La distribution $u est basée
La distribution ubuntu est basée sur
$ unset d
$ echo " La distribution $u est basée
La distribution ubuntu est basée sur
$ readonly u
$ u = Ubuntu
bash : u : variable en lecture seule
sur $d ."
debian .
sur $d ."
.
3.5 Export
Par défaut, une variable n'est accessible que depuis le shell où elle a été dénie. Dans l'exemple suivant, la
variable
d
est déclarée sous l'invite du shell courant puis est achée par un script lancé depuis ce même shell.
Ce dernier ne connaît pas la variable d : rien ne s'ache.
$
$
$
$
d = debian
echo ' echo " $d est une distribution Gnu / Linux ." ' > deb . sh
chmod u + x deb . sh
./ deb . sh
est une distribution Gnu / Linux .
7
La commande
export
permet d'exporter une variable de manière à ce que son contenu soit visible par les
scripts et autres sous-shells. Les variables exportées peuvent être modiées dans le script, mais ces modications
ne s'appliquent qu'au script ou au sous-shell. Dans l'exemple suivant, le script
d
deb.sh peut accéder à la variable
exportée mais les modications restent locales au script. Une fois celui-ci terminé, la modication disparaît.
$ d = debian
$ export d
$ echo 'd = gentoo ; echo " $d est une distribution Gnu / Linux ." ' >> deb . sh
$ ./ deb . sh
debian est une distribution Gnu / Linux .
gentoo est une distribution Gnu / Linux .
$ echo " $d est une distribution Gnu / Linux ."
debian est une distribution Gnu / Linux .
3.6 Accolades
Les accolades de base
{} permettent d'identier
liste. On peut vouloir
contenant le nom de chier
le nom d'une variable. Imaginons la variable
copier le chier
liste1
en
liste2.
fichier
$ fichier = liste
$ cp $fichier1 $fichier2
cp : opérande de fichier manquant
Saisissez cp -- help pour plus d ' informations .
Cela ne fonctionne pas car ce n'est pas
$fichier
qui est interprété mais
$fichier1
et
$fichier2
qui
n'existent pas.
$ cp $ { fichier }1 $ { fichier }2
Dans ce cas, cette ligne équivaut à :
$ cp liste1 liste2
3.7 Variables système
En plus des variables que l'utilisateur peut dénir lui-même, le shell est lancé avec un certain nombre
de variables prédénies utiles pour certaines commandes et accessibles par l'utilisateur. Le contenu de ces
variables système peut être modié mais il faut alors faire attention car certaines ont une incidence directe sur
le comportement du système. Le tableau suivant en décrit quelques unes.
8
Variable
Contenu
Chemin d'accès du répertoire utilisateur. Répertoire par défaut
HOME
de la commande
PATH
cd.
Liste de répertoires, séparés par des
':'
où le shell recherche les
commandes externes et autres scripts et exécutables. La recherche
se fait dans l'ordre des répertoires saisis.
PS1
Prompt String1,
PS2
Prompt String2,
chaîne représentant le prompt standard aché à
l'écran par le shell en attente de saisie de commandes.
chaîne représentant un prompt secondaire au cas
où la saisie doit être complétée.
SHELL
Chemin complet du shell de connexion de l'utilisateur.
LANG
Dénition de la langue à utiliser ainsi que du jeu de caractères.
USER
Nom de l'utilisateur en cours.
LOGNAME
Nom du login utilisé lors de la connexion.
HISTSIZE
Taille en nombre de lignes de l'historique des commandes.
OLDPWD
Chemin d'accès du répertoire accédé précédemment.
PWD
Chemin d'accès au répertoire courant.
3.8 Variables spéciales
Il s'agit de variables accessibles uniquement en lecture et dont le contenu est généralement contextuel. En
voici quelques unes :
Variable
$?
$$
$!
$-
Contenu
Code de retour de la dernière commande exécutée.
PID du shell actif.
PID du dernier processus lancé en arrière-plan.
Les options du shell.
3.9 Longueur d'une chaîne
Il est possible d'obtenir la longueur d'une chaîne avec le caractère
#.
$ sys = Linux
$ echo " Longueur du mot $sys = $ {# sys }"
Longueur du mot Linux = 5
3.10 Tableaux et champs
Deux moyens sont disponibles pour déclarer un tableau, l'un avec l'utilisation des crochets
la création globale. Le premier élément est à la position
0
et le dernier à la position
contenu du tableau, il faut mettre la variable et l'élément entre accolades.
$ Distribution [0]=" Debian "
$ Distribution [1]=" Gentoo "
$ Distribution [2]=" Slackware "
$ echo $ { Distribution [1]}
Gentoo
9
1023.
[], l'autre avec
Pour accéder au
ou :
$ Distribution =( Debian Gentoo Slackware )
$ echo $ { Distribution [2]}
Slackware
Pour lister tous les éléments :
$ echo $ { Distribution [*]}
Debian Gentoo Slackware
Pour connaître le nombre d'éléments :
$ echo $ {# Distribution [*]}
3
Si l'index est une variable, il est inutile de la faire précéder par
$
:
$ i =0
$ echo $ { Distribution [ i ]}
Debian
3.11 Variables typées
typeset -i. L'avantage est qu'il deexpr (décrite plus loin). La commande
Les variables peuvent être typées en entier (integer ) avec la commande
vient possible d'eectuer des calculs et des comparaisons sans passer par
let
ou
((...))
permet des calculs sur des variables entières.
Opérateur
+
%
<
==
&&
&
-
*
Rôle
/
Opérations simples.
Modulo.
> <=
!=
||
| ^
>=
Comparaisons,
1
si vraie,
0
si faux.
Égal ou diérent.
Comparaisons liées par un opérateur logique.
Logique binaire
AND, OR
et
XOR.
$ typeset -i x
$ x =6*7
$ echo $x
42
$ x = x *3
$ echo $x
126
$ typeset -i y
$ y =5
$ let x = y +5 x = x * y
$ echo $x
50
4 Conguration de bash
4.1 Fichiers de conguration
Le shell bash peut être lancé dans plusieurs modes :
le shell interactif de connexion (login
shell ),
le shell interactif simple,
le shell non interactif.
Selon son mode de démarrage, le shell va chercher et exécuter divers scripts et chiers de conguration.
Un chier de conguration est un script shell : une séquence de commandes individuelles ayant pour but de
congurer l'environnement de l'utilisateur.
10
4.1.1 Shell de connexion
Le shell de connexion est lancé après la saisie du login et du mot de passe sur la console. C'est celui précisé
à la n de chaque ligne de
/etc/passwd.
Dans ce mode, le shell cherche à exécuter, dans l'ordre indiqué et
s'ils sont présents, les chiers de conguration suivants :
1.
/etc/profile
2. le premier chier trouvé de la liste ordonnée suivante :
(a)
(b)
(c)
~/.bash_profile
~/.bash_login
~/.profile
Remarque 2
Le chier
/etc/profile exécute automatiquement un autre chier de conguration de nom /etc/bash.bashrc
~/.profile exécute automatiquement le chier ~/.bashrc s'il existe.
si ce dernier existe. De même,
À la déconnexion, il tente d'exécuter
~/.bash_logout
4.1.2 Shell simple
Le shell interactif simple correspond à l'exécution de bash dans une fenêtre (xterm,
une console ou à la main (taper
~/.bashrc seront exécutés
1. /etc/bash.bashrc
2. ~/.bashrc
bash
dans une console). Dans ce cas, seuls les chiers
gnome-terminal, ...),
/etc/bash.bashrc et
s'ils existent, et dans l'ordre suivant :
4.1.3 Mode non interactif
Le shell peut être lancé en mode non interactif. C'est généralement le cas lorsqu'on exécute un script. Dans
ce cas, il n'y a aucun chiers de conguration exécuté par défaut au démarrage, sauf si on précise une variable
appelée
BASH_ENV
qui contient le chemin d'un script. Dans ce cas, bash charge et exécute ce chier avant le
début de l'exécution du script ou de la commande.
5 Structure et exécution d'un script
Le shell n'est pas qu'un simple interpréteur de commandes, mais dispose d'un véritable langage de programmation avec notamment une gestion des variables, des tests, des boucles, des opérations sur les variables,
des fonctions ...
Toutes les instructions et commandes sont regroupées au sein d'un script. Lors de son exécution, chaque
ligne sera lue et exécutée. Une ligne peut être composée de commandes internes ou externes, de commentaires,
ou être vide. Plusieurs commandes par lignes sont possibles, séparées par ';' ou liées conditionnellement par
&&
ou
||.
Par convention, les noms des scripts shell se terminent (pas obligatoirement) par .sh pour le Bourne
Shell et le Bourne Again Shell, par
.ksh
pour le Korn Shell et par
.csh
pour le C Shell.
Pour rendre un script directement exécutable :
$ chmod u + x monscript
Pour l'exécuter :
$ ./ monscript
Pour éviter le
./
:
$ PATH = $PATH :.
$ monscript
Quand un script est lancé, un nouveau shell ls est créé pour exécuter chacune de ses commandes. Une
commande interne du script est directement exécutée par le nouveau shell. Pour une commande externe, un
nouveau shell ls est créé et chargé de l'exécuter. Enn, dans le cas d'un script shell, un nouveau shell ls est
lancé pour le lire ligne par ligne.
Une ligne de commentaire commence toujours par le caractère
d'une ligne comportant déjà des commandes.
11
#.
Un commentaire peut être placé en n
# La ligne suivante effectue un ls
ls # La ligne en question
La première ligne a une importance particulière car elle permet de préciser quel shell va exécuter le script :
#!/ bin / bash
La première ligne ci-dessus d'un script indique que ce dernier doit être exécuté par le shell
bash.
5.1 Arguments d'un script
5.1.1 Paramètres de position
Les paramètres de position sont des variables spéciales utilisées lors d'un passage de paramètres à un script.
Variable
$0
$n
$#
$*
$@
Contenu
Nom de la commande (du script).
$1, $2, $3, ...
les paramètres passés au script.
Nombre total de paramètres passés au script.
Liste de tous les paramètres au format "$1 $2 $3 ...".
Liste des paramètres sous forme d'éléments distincts.
$ cat param . sh
#!/ bin / bash
echo " Nom : $0 "
echo " Nombre de parametres : $ #"
echo " Parametres : 1= $1 2= $2 3= $3 "
echo " Liste : $ *"
echo " Elements : $@ "
$ ./ param . sh debian gentoo slackware
Nom : ./ param . sh
Nombre de parametres : 3
Parametres : 1= debian 2= gentoo 3= slackware
Liste : debian gentoo slackware
Elements : debian gentoo slackware
La diérence entre
$@
et
$*
ne semble pas évidente. Reprenons l'exemple précédent avec une petite modi-
cation :
$ ./ param . sh debian " gentoo slackware "
Nom : ./ param . sh
Nombre de parametres : 2
Parametres : 1= debian 2= gentoo slackware 3=
Liste : debian gentoo slackware
Elements : debian gentoo slackware
Cette fois, il n'y a que deux paramètres qui sont passés. Pourtant les listes semblent visuellement identiques.
En fait si la première contient bien :
" debian gentoo slackware "
la deuxième contient :
" debian " " gentoo slackware "
Soit bien deux éléments. Dans le premier exemple on avait :
" debian " " gentoo " " slackware "
12
5.1.2 Redénition des paramètres
Outre le fait de lister les variables, la commande
set permet de redénir le contenu des variables de position.
Avec :
set valeur1 valeur2 valeur3 ...
$1
prendra comme contenu
valeur1, $2 valeur2
et ainsi de suite.
$ cat param2 . sh
#!/ bin / bash
echo " Avant set :"
echo " Nombre de paramètres : $ #"
echo " Paramètres : 1= $1 2= $2 3= $3 "
echo " Liste : $ *"
set redhat suse gentoo
echo " Après set :"
echo " Nombre de paramètres : $ #"
echo " Paramètres : 1= $1 2= $2 3= $3 "
echo " Liste : $ *"
$ ./ param2 . sh debian ubuntu mint gnewsence
Avant set :
Nombre de paramètres : 4
Paramètres : 1= debian 2= ubuntu 3= mint
Liste : debian ubuntu mint gnewsence
Après set :
Nombre de paramètres : 3
Paramètres : 1= redhat 2= suse 3= gentoo
Liste : redhat suse gentoo
5.1.3 Réorganisation des paramètres
La commande
shift
est une autre commande permettant de modier la structure des paramètres de
$2 devient
$2 et ainsi de suite. Le $1 originel disparaît. $# , $* et $@ sont redénis en conséquence. La
commande shift suivie d'une valeur n eectue un décalage de n éléments. Ainsi avec shift 4, $5 devient
$1, $6 devient $2, ...
position. Un simple appel décale tous les paramètres d'une position en supprimant le premier :
$1, $3
devient
$ cat ./ param3 . sh
#!/ bin / bash
shift 2
echo " Nombre de paramètres : $ #"
echo " Liste : $ *"
$ ./ param3 . sh debian ubuntu mint
Nombre de paramètres : 1
Liste : mint
5.1.4 Sortie d'un script
La commande
exit
0 (pas d'erreur)
0 à 255 peut être précisée. On récupère la valeur de sortie par la variable
permet de mettre n à un script. Par défaut la valeur retournée est
mais n'importe quelle autre valeur de
$?.
5.2 Environnement du processus
En principe seules les variables exportées sont accessibles par un processus ls. Si on souhaite visualiser
l'environnement lié à un ls (dans un script par exemple), on utilise la commande
La commande
env
env.
permet de redénir aussi l'environnement du processus à lancer. Cela peut être utile
lorsque le script doit accéder à une variable qui n'est pas présente dans l'environnement du père, ou qu'on ne
souhaite pas exporter. La syntaxe est :
env var1 = valeur var2 = valeur ... commande
Dans le cas de bash,
env
n'est pas indispensable, on peut donc utiliser la syntaxe suivante :
13
var1 = valeur var2 = valeur ... commande
Si la première option est le signe
-
alors c'est tout l'environnement existant qui est supprimé pour être
remplacé par les nouvelles variables et valeurs.
$ cat d . sh
#!/ bin / bash
echo " d = $d "
$ unset d
$ ./ d . sh
d=
$ env d = debian ./ d . sh
d = debian
$ d = debian ./ d . sh
d = debian
$ export d = DEBIAN
$ ./ d . sh
d = DEBIAN
$ env - ./ d . sh
d=
5.3 Substitution de commande
Le mécanisme de substitution permet de placer le résultat de commandes simples ou complexes dans une
variable. On place les commandes à exécuter entre des accents graves ` ([Alt
Gr] 7 sur les claviers français).
$ mon_unix = ` uname -a | cut -d ' ' -f10 `
$ echo $mon_unix
GNU / Linux
Notons que seul le canal de sortie standard est aecté à la variable. Le canal d'erreur standard est toujours
l'écran.
5.4 Tests de conditions
$?.
La commande
test permet d'eectuer des tests de
0 alors la condition est réalisée.
conditions. Le résultat est récupérable par la variable
Si ce résultat est
5.4.1 Tests sur une chaîne
$
$
0
$
1
$
$
0
test
test
test
test
-z "variable" : zero, retourne OK si la variable est vide (exemple, test -z "$a").
-n "variable" : non zero, retourne OK si la variable n'est pas vide (texte quelconque).
"variable" = chaîne : OK si les deux chaînes sont identiques.
"variable" != chaîne : OK si les deux chaînes sont diérentes.
d=
test -z " $d " ; echo $ ?
test -n " $d " ; echo $ ?
d = debian
test " $d " = debian ; echo $ ?
Attention à bien placer les variables contenant du texte entre guillemets. Dans le cas contraire, un bug se
produira si la variable est vide :
$ s1 =
$ s2 = azerty
$ [ $s1 = $s2 ] && echo " ok "
bash : [: = : opérateur unaire attendu
alors que :
[ " $s1 " = " $s2 " ] && echo " ok "
ne produit pas d'erreur.
14
5.4.2 Tests sur les valeurs numériques
Les chaînes à comparer sont converties en valeurs numériques. Bash ne gère que des valeurs entières. La
syntaxe est :
test valeur1 opérateur valeur2
Les opérateurs sont :
$ a =10
$ b =20
$ test
0
$ test
1
$ test
10 est
-eq
(=),
-ne (<>), -lt (<), -gt
(>),
-le
(<=) et
-ge (>=).
" $a " - ne " $b " ; echo $ ?
" $a " - ge " $b " ; echo $ ?
" $a " - lt " $b " && echo " $a est inférieur à $b "
inférieur à 20
5.4.3 Tests sur les chiers
La syntaxe est :
test critère fichier
-f (chier normal), -d (répertoire), -c (chier en mode caractère), -b (chier en mode
-p (tube nommé), -r (autorisation en lecture), -w (autorisation en écriture), -x (autorisation en exécu-s (chier non vide), -e (chier existe), -L (chier est un lien symbolique).
Les critères sont :
bloc),
tion),
$ ls param . sh
- rwxr - -r - - 1 etudiant etudiant 252 janv .
$ test -f param . sh ; echo $ ?
0
$ test -x param . sh ; echo $ ?
0
$ test -d param . sh ; echo $ ?
1
5 20:13 param2 . sh
5.4.4 Tests combinés par des critères ET, OU et NON
On peut eectuer plusieurs tests avec une seule commande. Les options de combinaison sont les mêmes
que pour la commande
find
:
-a
(AND),
-o
(OR), ! (NOT). Les parenthèses peuvent être utilisées pour le
groupement des combinaisons mais elles doivent être verrouillées
\(...\).
$ test \( ! -d param . sh \) -a -x " param . sh " && \
> echo " param . sh n ' est pas un répertoire et il est exécutable ."
param . sh n ' est pas un répertoire et il est exécutable .
5.4.5 Syntaxe allégée
Le mot
test
peut être remplacé par les crochets ouverts et fermés
[ ... ].
Il faut laisser un espace après
le crochet ouvert et avant le crochet fermé.
$ [ " $a " - lt " $b " ] && echo " $a est inférieur à $b "
10 est inférieur à 20
bash intègre une commande interne de test qui se substitue au programme
test (/usr/bin/test).
Dans
la pratique, la commande interne est entièrement compatible avec la commande externe mais bien plus rapide
car il n'y a pas de création de nouveau processus. Pour forcer l'utilisation de la commande interne, on utilise
les doubles crochets
[[ ... ]].
$ [[ " $a " - lt " $b " ]] && echo " $a est inférieur à $b "
10 est inférieur à 20
15
5.5 if ... then ... else ... La structure
if then else fi
est une structure de contrôle conditionnelle.
if < commandes_condition >
then
< commandes exécutées si la condition est réalisée >
else
< commandes exécutées si la condition n ' est pas réalisée >
fi
On peut aussi préciser
elif,
en fait un
else if.
Si la dernière condition n'est pas réalisée, on teste une
nouvelle.
$ cat param4 . sh
#!/ bin / bash
if [[ $ # - ne 0 ]]
then
echo " $ # paramètres en ligne de commande ."
else
echo " Aucun paramètre "
fi
5.6 Choix multiples : case
La commande
case ... esac
permet de vérier le contenu d'une variable ou d'un résultat de manière
multiple.
case valeur
modele1 )
modele2 )
...
*)
esac
in
commandes ;;
commandes ;;
commandes_par_défaut ;;
Le modèle est soit un simple texte, soit composé des caractères spéciaux décrits par le tableau suivant.
Chaque bloc de commandes lié au modèle doit se terminer par deux points-virgules. Dès que le modèle est
vérié, le bloc de commandes correspondant est exécuté. L'étoile en dernière position permet d'exécuter l'action
par défaut si aucun critère n'est vérié. Elle est facultative.
Caractère
*
?
[...]
[!...]
|
Rôle
N'importe quelle chaîne (même vide).
Un (seul) caractère quelconque.
Une plage de caractères.
Négation de la plage de caractères.
OU logique.
#!/ bin / bash
if [ $ # - ne 1 ]
then
echo " Erreur : Un et un seul paramètre attendu ."
exit 1
fi
case $1 in
[a - zA - Z ]*) echo " Le paramètre commence par une lettre .";;
[0 -9]*) echo " Le paramètre commence par un chiffre .";;
*) echo " Le paramètre commence par un autre caractère .";;
esac
exit 0
16
5.7 Saisie de l'utilisateur
La commande
read permet à l'utilisateur de saisir une chaîne et de la placer dans une ou plusieurs variables.
[Entrée].
La saisie doit être validée par la touche
read var1 [ var2 ...]
Si plusieurs variables sont précisées, le premier mot ira dans
var1,
le second dans
var2,
et ainsi de suite.
S'il y a moins de variables que de mots, tous les derniers mots vont dans la dernière variable.
$ cat read . sh
#!/ bin / bash
echo -e " Continuer ( O / o / N / n )? \ c "
read reponse
case $reponse in
[ Oo ]) echo " Oui , on continue ";;
[ Nn ]) echo " Non , on s ' arrête "; exit 0;;
*) echo " Erreur de saisie "; exit 1;;
esac
echo -e " Tapez deux mots ou plus : \ c "
read mot1 mot2
echo -e " mot1 = $mot1 \ nmot2 = $mot2 "
exit 0
$ ./ read . sh
Continuer ( O / o / N / n )? o
Oui , on continue
Tapez deux mots ou plus : Salut tout le monde !
mot1 = Salut
mot2 = tout le monde !
5.8 Les boucles
Elles permettent la répétition d'un bloc de commandes soit un nombre limité de fois, soit conditionnellement. Toutes les commandes à exécuter dans une boucle se placent entre les commandes
do
et
done.
5.8.1 Boucle for
La boucle
for
ne se base pas sur une quelconque incrémentation de valeur mais sur une liste de valeurs,
de chiers ...
for var in < liste >
do
< commandes à exécuter >
done
La liste représente un certain nombre d'éléments qui seront successivement attribués à
Avec une variable
$ cat for1 . sh
#!/ bin / bash
for param in $@
do
echo " $param "
done
$ ./ for1 . sh ab cde
ab
cde
17
var.
Liste implicite
Si on ne précise aucune liste à
for,
alors c'est la liste des paramètres qui est implicite. Ainsi, la boucle du
script précédent aurait pu être :
for param
do
echo " $param "
done
Avec une liste d'éléments explicite
Chaque élément situé après le
in
sera utilisé pour chaque itération de la boucle, l'un après l'autre.
$ cat for2 . sh
#!/ usr / bin / sh
for element in elt1 elt2
do
echo " $element "
done
$ ./ for2 . sh
elt1
elt2
Avec des critères de recherche sur des noms de chiers
Si un ou plusieurs éléments de la liste correspond à un chier ou à un motif de chiers présents dans le
répertoire courant, la boucle
for
considère l'élément comme un nom de chier.
$ cat for3 . sh
#!/ bin / bash
echo " Liste des fichier du répertoire courant :"
for fichier in *
do
echo -e " $fichier "
done
$ ./ for3 . sh
Liste des fichier du répertoire courant :
Bureau
case . sh
Documents
Downloads
spim -8.0
...
Avec une substitution de commande
Toute commande produisant une liste de valeurs peut être placée à la suite du in à l'aide d'une substitution de commande. La boucle
for
prendra le résultat de cette commande comme la liste d'éléments sur
laquelle boucler.
$ cat for4 . sh
#!/ bin / bash
echo -e " Liste des utilisateurs dans / etc / passwd : \ c "
for user in ` cat / etc / passwd | cut -d : -f1 `
do
echo -e " $user \ c "
done
$ ./ for4 . sh
Liste des utilisateurs dans / etc / passwd : root daemon bin sys sync games ...
18
5.8.2 Boucle while
while condition
do
commandes
done
Tant que la condition est réalisée, le bloc de commande est exécuté. On sort si la condition n'est plus
valable.
$ cat while1 . sh
#!/ bin / bash
while echo -e " Chaine ? \ c "; read nom ; [ -z " $nom " ]
do
echo " ERREUR : pas de saisie "
done
echo " Vous avez saisi : $nom "
Lecture d'un chier ligne par ligne
Elle peut se faire, soit en utilisant un tube (pipe) :
#!/ bin / bash
cat fichier . txt | while read ligne
do
echo " $ligne "
done
ou bien par redirection de l'entrée :
#!/ bin / bash
while read ligne
do
echo " $ligne "
done < fichier . txt
5.8.3 Boucle until
until condition
do
< commandes >
done
La boucle
until
est analogue à la boucle
while.
La seule diérence est que, contrairement à
lorsque la condition est réalisée qu'on sort de la boucle
until.
while,
c'est
5.8.4 true et false
La commande
true
ne fait rien d'autre que de renvoyer
0.
La commande
false
renvoie toujours 1. De
cette manière il est possible de réaliser des boucles innies. La seule manière de sortir de ces boucles est un
exit
ou un
break.
Par convention, tout programme qui ne retourne pas d'erreur, retourne
0,
retournant une erreur, ou un résultat à interpréter, retourne autre chose que
tandis que tout programme
0.
C'est l'inverse en logique
booléenne.
5.8.5 break et continue
La commande
done.
break
permet d'interrompre une boucle. Dans ce cas le script continue après le mot clé
Elle peut prendre un argument numérique indiquant le nombre de boucles à sauter dans le cas de
boucles imbriquées.
while true
do
echo -e " Chaine ? \ c "
read a
19
if [ -z " $a " ]
then
break
fi
done
continue permet de relancer une boucle et d'eectuer un nouveau passage. Elle peut prendre
n boucles). Le script
commande do.
La commande
un argument numérique indiquant le nombre de boucles à relancer (on remonte de
redémarre à la
5.9 Les fonctions
Les fonctions sont des bouts de scripts nommés, directement appelés par leur nom, pouvant accepter des
paramètres et retourner des valeurs. Les noms de fonctions suivent les mêmes règles que les variables sauf
qu'elles ne peuvent pas être exportées.
nom_fonction ()
{
commandes
return
}
Les fonctions peuvent être soit tapées dans le script courant, soit dans un autre chier pouvant être inclus
dans l'environnement. Pour cela il faut saisir :
. fichier
Le point suivi d'un nom de chier charge son contenu (fonctions et variables) dans l'environnement courant.
return permet d'aecter une valeur de retour à une fonction.
exit pour sortir d'une fonction car sinon on quitte le script.
La commande
commande
Il ne faut surtout pas utiliser la
$ cat fonctions
ll ()
{
ls -l $@
}
li ()
{
ls -i $@
}
$ . fonctions
$ li
269361 Bureau
269726 case . sh
269365 Documents
...
5.10 Calculs et expressions
5.10.1 expr
La commande
expr
permet d'eectuer des calculs sur des valeurs numériques, des comparaisons, et de la
recherche dans des chaînes de texte.
20
Opérateur
+
*
/
%
!=
=
<
>
<=
>=
:
Rôle
Addition.
Soustraction.
Multiplication. L'étoile étant reconnue par le shell comme un caractère spécial, il faut
la verrouiller avec un antislash :
\*.
Division.
Modulo.
Diérent. Ache 1 si diérent, 0 sinon.
Égal. Ache 1 si égal, 0 sinon.
Inférieur. Ache 1 si inférieur, 0 sinon.
Supérieur. Ache 1 si supérieur, 0 sinon.
Inférieur ou égal. Ache 1 si inférieur ou égal, 0 sinon.
Supérieur ou égal. Ache 1 si supérieur ou égal, 0 sinon.
Recherche dans une chaîne. Exemple :
commence par
d.
Syntaxe particulière :
expr debian : "d*" retourne 1 car debian
expr debian : ".*" retourne la longueur de
la chaîne.
Notons qu'il faut toujours laisser des espaces entre les opérateurs et leurs opérandes.
$ expr 7 + 3
10
$ expr 7 \* 3
21
$ a = $ ( expr 13 - 10)
$ echo $a
3
$ cat expr . sh
#!/ bin / bash
somme =0
compteur =1
N =10
echo " Calcul de la somme des $N premiers nombres entiers :"
while [ " $compteur " - le " $N " ]
do
somme = $ ( expr $somme + $compteur )
echo " itération = $compteur , somme = $somme "
compteur = $ ( expr $compteur + 1)
done
$ ./ expr . sh
Calcul de la somme des 10 premiers nombres entiers :
itération =1 , somme =1
itération =2 , somme =3
itération =3 , somme =6
...
itération =10 , somme =55
5.10.2 Calculs avec bash
bash propose une forme simple de calculs sur les entiers, en plaçant l'opération entre
$ a =1;
$ echo
2
$ b =6;
$ echo
12
$((...))
a = $ (( a +1))
$a
a = $ (( a * b ))
$a
On n'a pas besoin de spécier les
$
des noms des variables entre les doubles parenthèses.
21
:
5.11 Une variable dans une autre variable
Considérons l'exemple suivant :
$ x = debian
$ y=x
$ echo $y
x
Comment acher le contenu de
x
et pas simplement
On peut utiliser pour cela la commande
précédée par deux
$,
eval
x?
qui essaie d'interpréter, si possible, la valeur d'une variable
comme étant une autre variable.
$ eval echo \ $$y
debian
$ cat eval . sh
#!/ bin / bash
cpt =1
for i in a b c
do
eval $i = $cpt
cpt = $ (( cpt +1))
done
echo $a $b $c
$ ./ eval . sh
1 2 3
5.12 Traitement des signaux
La commande
trap
permet de modier le comportement du script à la réception d'un signal.
Commande
Réaction
trap signaux
trap 'commandes' signaux
trap signaux
Dans l'exemple suivant,
trap
Ignore les signaux. Exemple,
ignore les signaux 2 et 3.
Restaure les actions par défaut pour les signaux indiqués.
empêche l'exécution du
$ cat trap . sh
#!/ bin / bash
ignorer ()
{ echo " Ctrl + C ignoré "
}
sortir ()
{ echo " Signal 15 reçu "; exit 0
}
trap ignorer 2
trap sortir 15
while true
do
true
done
$ ./ trap . sh
^ C Ctrl + C ignoré
^ C Ctrl + C ignoré
Depuis un autre terminal ou console :
$ kill -2 12456
$ kill -2 12456
$ kill -15 12456
trap 2 3
Pour chaque signal reçu, exécution des commandes indiquées.
# aucun effet
# aucun effet
# SIGTERM
Sur le premier terminal :
Ctrl + C ignoré
Ctrl + C ignoré
Signal 15 reçu
22
[Ctrl] C (SIGINT)
et intercepte le signal
SIGTERM
:

Documents pareils