Projet

Général

Profil

Petit precis de shell » Historique » Version 12

Julien Enselme, 10/08/2013 11:47
itération : rédaction

1 3 Julien Enselme
{{toc}}
2 2 Julien Enselme
3 6 Florent Torregrosa
Le shell est un langage assez particulier qu'on ne connait pas forcément en arrivant à centrale et qu'on a pas forcément l'occasion de beaucoup pratiquer. Le but de ce document est de rappeler les quelques bases du langage et de fournir quelques solutions standard à des problèmes courants afin que le nouveau membre du club Drupal ne soit pas désemparé et puisse comprendre les scripts. Il ne se veut en aucun cas un cours/tuto complet et exhaustif.
4 1 Julien Enselme
5 3 Julien Enselme
h1. Quelques rappels d'Unix
6 3 Julien Enselme
7 3 Julien Enselme
Le langage shell est le langage de script qui vient par défaut avec _tous_ les Unix. En effet, même si désormais d'autres interpréteurs plus modernes sont désormais répandus (bash, csh, zsh, etc.), ils ont tous conservé la compatibilité avec le shell.
8 3 Julien Enselme
9 3 Julien Enselme
Comme pour la plupart des langages de script, il existe deux façons d'exécuter des instructions shell :
10 3 Julien Enselme
11 3 Julien Enselme
* directement dans l'interpréteur
12 3 Julien Enselme
* dans un script shell
13 3 Julien Enselme
14 3 Julien Enselme
Pour lancer un interpréteur shell, rien de plus simple : lancer un terminal (graphique ou tty). Et oui, le shell comprend toutes les commandes Unix que vous avez vues en début d'année (pwd, cd, cp). Vous pouvez donc les réutiliser _telles quelles_ dans vos scripts et utiliser son bon terminal pour faire des boucles, des conditions et j'en passe.
15 3 Julien Enselme
16 1 Julien Enselme
h1. Les bases du shell
17 3 Julien Enselme
18 4 Julien Enselme
Il est très important de comprendre et de garder à l'esprit qu'en shell tout est :
19 4 Julien Enselme
20 4 Julien Enselme
* chaîne de caractères (y compris les nombres) ! Entrez @echo 1 + 1@ dans le terminal pour vous en convaincre.
21 4 Julien Enselme
* commande et que donc elles peuvent prendre des arguments (cela s'éclaircira plus tard)
22 4 Julien Enselme
23 4 Julien Enselme
h2. Syntaxe de base
24 4 Julien Enselme
25 4 Julien Enselme
Les commandes s'écrivent soit :
26 4 Julien Enselme
27 6 Florent Torregrosa
* les unes à la suite des autres séparées par ; (peu recommandé)
28 4 Julien Enselme
* séparées les unes des autres par un saut de ligne
29 4 Julien Enselme
30 4 Julien Enselme
Chaque commande peut prendre des arguments de deux types :
31 4 Julien Enselme
32 4 Julien Enselme
* les arguments courts (l, r, h pour @ls@ par exemple) qui sont passés comme suit : @CMD -ARG@
33 4 Julien Enselme
* les arguments longs (recursive pour @rsync@ par exemple) qui se passent comme ceci : @CMD --ARGUMENT@
34 4 Julien Enselme
35 4 Julien Enselme
Il est évidement possible de passer plusieurs arguments à une même commande.
36 4 Julien Enselme
37 6 Florent Torregrosa
{{tip(Certains arguments existent sous une forme courte et une forme longue. Consulter le manuel de la commande pour plus de détails. Le manuel contient également la liste complète des arguments supportés par une commande.)}}
38 4 Julien Enselme
39 4 Julien Enselme
{{note(Certains commandes ne respectent pas la convention énoncée ce-dessus. Leurs arguments long se passent avec un seul - (find en est un exemple))}}
40 4 Julien Enselme
41 5 Julien Enselme
h2. Valeurs de retour des commandes et exception
42 5 Julien Enselme
43 6 Florent Torregrosa
Une fois qu'une commande s'est exécutée, elle renvoie une valeur de retour afin "d'informer" l'utilisateur. Cette valeur permet en effet de savoir si la commande s'est exécutée correctement. Voici les valeurs de retour possibles et leur signification :
44 5 Julien Enselme
45 5 Julien Enselme
* 0 : tout va bien
46 5 Julien Enselme
* 1 : erreur
47 5 Julien Enselme
* 2 : erreur grave
48 5 Julien Enselme
49 6 Florent Torregrosa
Vous pouvez vous aussi utiliser ces valeurs de retour. Par défaut, un script qui se complète correctement retourne 0. Mais vous pouvez (par exemple si un utilisateur tente d'exécuter un script qui nécessite un argument sans) retourner un autre code d'erreur avec la commande @exit@. Il suffit de lui passer le code qu'elle doit retourner. Votre script s'arrêtera alors avec le code d'erreur spécifié.
50 5 Julien Enselme
51 4 Julien Enselme
h2. Conditions et itérations
52 7 Julien Enselme
53 11 Julien Enselme
h3. Conditions if … else …
54 7 Julien Enselme
55 7 Julien Enselme
La structure générale d'une condition est la suivante :
56 7 Julien Enselme
57 7 Julien Enselme
<pre>
58 7 Julien Enselme
<code>
59 7 Julien Enselme
if QQC
60 7 Julien Enselme
then
61 7 Julien Enselme
    CMDS
62 7 Julien Enselme
else
63 7 Julien Enselme
    CMDS
64 7 Julien Enselme
fi
65 7 Julien Enselme
</code>
66 7 Julien Enselme
</pre>
67 7 Julien Enselme
68 7 Julien Enselme
Le @else@ est facultatif. Il est aussi possible de regrouper @if@ et @then@ en une seule ligne comme ceci : @if QQC ; then@.
69 7 Julien Enselme
70 7 Julien Enselme
La question que vous devriez avoir est que mettre à la place de @QQC@. Il y a deux possibilités :
71 7 Julien Enselme
72 7 Julien Enselme
* la fonction @test@
73 7 Julien Enselme
* une commande
74 7 Julien Enselme
75 11 Julien Enselme
h4. La fonction test
76 7 Julien Enselme
77 7 Julien Enselme
{{important(Dans toute la suite, il faudra faire très *attention aux espaces*)}}
78 7 Julien Enselme
79 7 Julien Enselme
La fonction @test@ s'utilise en général comme suit : @if [ ARGS ]@
80 7 Julien Enselme
81 7 Julien Enselme
*IMPORTANT* : La syntaxe *@if [[ ARGS ]]@* n'est valide qu'avec *bash*. Voir [[Petit_precis_de_shell#Différences notables avec bash|Différences notables avec bash]]
82 7 Julien Enselme
83 10 Julien Enselme
Pour faire un test, il suffit ensuite de passer les bons arguments à la commande. Par exemple, pour tester si une chaîne est vide : @if [ -z $chaine ]. Si l’argument a besoin de deux paramètres pour fonctionner, mettre un paramètre de chaque côté de celui-ci. Par exemple, pour faire un test d’égalité de chaîne de caractères : @CHAINE1 = CHAINE2@.
84 10 Julien Enselme
85 10 Julien Enselme
On peut aussi combiner les arguments avec des ET et des OU avec les options @-a@ et @-o@. Le caractère "!" permet de faire une négation.
86 10 Julien Enselme
87 10 Julien Enselme
Voir ci-dessous pour la liste complète.
88 10 Julien Enselme
89 10 Julien Enselme
{{important(En shell, tout est chaîne de caractère. Bien faire attention au type que l’on veut tester (chaîne ou nombre))}}
90 10 Julien Enselme
91 10 Julien Enselme
h5. Tests sur les chaînes de caractères
92 10 Julien Enselme
93 10 Julien Enselme
|_. Argument |_. Signification |
94 10 Julien Enselme
| = | égalité |
95 10 Julien Enselme
| -z | chaîne vide |
96 10 Julien Enselme
| -n | chaîne non vide |
97 10 Julien Enselme
98 10 Julien Enselme
h5. Tests sur les nombres
99 10 Julien Enselme
100 10 Julien Enselme
|_. Argument |_. Signification |
101 10 Julien Enselme
| -eq | égalité |
102 10 Julien Enselme
| -ne | non égalité |
103 10 Julien Enselme
| -lt | strictement plus petit |
104 10 Julien Enselme
| -gt | strictement plus grand |
105 10 Julien Enselme
| -ge | plus grand ou égal |
106 10 Julien Enselme
| -le | plus petit ou égal |
107 10 Julien Enselme
108 7 Julien Enselme
h4. Test avec une commande
109 1 Julien Enselme
110 10 Julien Enselme
Comme indiqué précédemment, une commande qui s’exécute correctement est considérée comme vrai. Ainsi, il est tout a fait possible, par exemple, pour savoir si on arrive à se connecter à un serveur mysql de faire simplement : @if mysql -h HOST -u asso -pTATA@.
111 10 Julien Enselme
112 10 Julien Enselme
{{tip(Parfois vous pourrez rencontrer des problèmes. Pensez alors à donner cette commande en argument à la fonction test)}}
113 7 Julien Enselme
114 12 Julien Enselme
h3. Boucles while/until
115 12 Julien Enselme
116 12 Julien Enselme
La structure générale est la suivante :
117 12 Julien Enselme
<pre>
118 12 Julien Enselme
while QQC
119 12 Julien Enselme
do
120 12 Julien Enselme
    CMD
121 12 Julien Enselme
done
122 12 Julien Enselme
</pre>
123 12 Julien Enselme
124 12 Julien Enselme
Il est possible de regrouper @while QQC@ et le @do@ en @while QQC ; do@. Le QQC peut être remplacer par exactement les mêmes choses que pour la condition. Se référer à cette section pour les précisions.
125 12 Julien Enselme
126 12 Julien Enselme
Le shell propose également le mot clé @until QQC@ qui fait une action jusqu’à ce que QQC soit réalisé.
127 12 Julien Enselme
128 12 Julien Enselme
h3. Boucle for
129 12 Julien Enselme
130 12 Julien Enselme
L’utilisation de la boucle for en shell ressemble à celle de python. La structure générale est la suivante :
131 12 Julien Enselme
<pre>
132 12 Julien Enselme
for var in `CMD`
133 12 Julien Enselme
do
134 12 Julien Enselme
   CMD
135 12 Julien Enselme
done
136 12 Julien Enselme
</pre>
137 12 Julien Enselme
138 12 Julien Enselme
La variable _var_ va alors prendre une à une les valeurs données par CMD. Par exemple, @for file in `ls`@ la variable var va prendre tour à tour le nom de tous les fichiers et dossiers donnés par la commande @ls@.
139 12 Julien Enselme
140 12 Julien Enselme
Vous pouvez également utiliser for pour boucler d’un nombre à un autre avec la syntaxe : @for i in {2..9}@
141 12 Julien Enselme
142 8 Julien Enselme
h1. Les fonctions
143 8 Julien Enselme
144 8 Julien Enselme
Parler de @local@ pour que les arguments soient internes à la fonction.
145 8 Julien Enselme
146 8 Julien Enselme
h1. Les redirections de flux
147 8 Julien Enselme
148 8 Julien Enselme
>, >>, 2>&1, &>, |&
149 8 Julien Enselme
150 9 Julien Enselme
h1. Paramètres de scripts
151 9 Julien Enselme
152 9 Julien Enselme
* $1, $2, …, $9
153 9 Julien Enselme
* $#
154 9 Julien Enselme
* $*
155 9 Julien Enselme
* $?
156 9 Julien Enselme
157 9 Julien Enselme
h1. Exécuter une commande
158 9 Julien Enselme
159 9 Julien Enselme
`` vs $(…)
160 9 Julien Enselme
161 8 Julien Enselme
h1. Importer une configuration
162 8 Julien Enselme
163 8 Julien Enselme
@. config-file.sh@
164 8 Julien Enselme
165 8 Julien Enselme
h1. Mode debug
166 8 Julien Enselme
167 8 Julien Enselme
@sh -x SCRIPT@
168 8 Julien Enselme
169 7 Julien Enselme
h1. Différences notables avec bash
170 9 Julien Enselme
171 9 Julien Enselme
h1. Divers
172 9 Julien Enselme
173 9 Julien Enselme
h2. Différences entre la sortie de ls et de find
174 9 Julien Enselme
175 9 Julien Enselme
ls : chemin relatif ; find auei : chemin absolu