diff --git a/unix/shell.tml b/unix/shell.tml index 08f5488..e7533f6 100644 --- a/unix/shell.tml +++ b/unix/shell.tml @@ -13,68 +13,165 @@
-Le machin qui interprète les commandes.
+Le mot shell signifie « coquille » en anglais. Il
+s'agit du programme que vous utilisez régulièrement à l'ENS, et qui
+interprète les commandes. Par exemple, vous y tapez pine
ou
+mutt
, forum
, cc
,
+mozilla
, etc.
+Mais quel rapport avec une coquille ? Eh bien, dans une coquille +vous pouvez mettre de l'eau, pour la porter ensuite à votre +bouche ; vous pouvez y mettre du sable avant de le verser dans des +bocaux ; en somme, une coquille est un récipient qui permet +de manipuler toutes sortes de contenus. Il en va de même du shell. C'est +un outil en mode texte qui permet l'exploitation d'un grand nombre de +ressources de l'ordinateur. +
+ ++Cette page vous donnera les rudiments pour exploiter les deux +principales fonctionnalités du shell : +
+ ++Le shell, comme le normalien, ne connaît que deux états : +
+ ++Le shell, une fois lancé, est inactif : il attend qu'on lui donne +des ordres. Quand on lui en donne un, il l'exécute ; et quand il a +terminé, il retourne à son état d'inactivité, en attente d'un nouveau +commandement. +
+ ++Quand le shell est inactif, il affiche une invite +(prompt en anglais), qui ressemble à cela : +
+ +chaland ~ $
+
++Un curseur, parfois clignotant, indique que le shell attend que vous lui +tapiez des instructions. +
La variable PATH
contient le
-chemin d'accès aux commandes. Le shell l'utilise pour trouver les
-commandes. Il s'agit d'une liste de répertoires séparés par des
-:
. La plupart des commandes sont en fait des programmes,
-c'est-à-dire des fichiers qu'on trouve dans le système de fichiers.
-Par exemple, quand vous tapez ls
, le shell exécute le fichier
-/bin/ls
. Pour trouver ce fichier, il cherche dans le premier
-répertoire du PATH
un fichier qui s'appelle ls
.
-S'il ne trouve pas, il cherche ensuite dans le deuxième répertoire et ainsi
-de suite.
+J'ai l'habitude de taper des commandes dans le shell, et je vois qu'il
+réagit. Mais comment comprend-il ce que je veux faire ?
-S'il ne trouve la commande dans aucun répertoire du PATH
, le shell
-affiche un message d'erreur. Exemple:
+Prenons un cas simple. Je tape la commande bonjour
à
+l'invite (prompt) du shell. Il va chercher à plusieurs endroits
+ce que j'entends par là :
+
bonjour
n'est pas une de
+ses commandes intégrées ; si c'est le cas, il l'exécute
+directement, sinon il passe à l'étape suivante ;PATH
, et qui indique le « chemin » où trouver les
+commandes que l'on appelle. Par exemple, si la variable PATH contient
+les répertoires :
+/usr/bin
/bin
et /home/toto/bin
,/usr/bin/bonjour
,/bin/bonjour
et /home/toto/bin/bonjour
;PATH
, il va renvoyer un message d'erreur
+en disant que désolé, il ne voit pas ce que l'on entend par
+bonjour
. Exemple :
+
+
+chaland ~ $ bonjour
+bonjour: Command not found
La variable PATH
consiste en
+une liste de répertoires séparés par des
+« :
». Si vous voulez voir à quoi ressemble votre
+PATH, tapez :
-chaland ~ $ sl
-sl: Command not found
+chaland ~ $ echo $PATH
+
-Certaines commandes du shell ne sont pas des programmes mais des commandes
-internes (builtins functions). Elles sont directement
-reconnues et exécutées par le shell. Un exemple de commande interne est
-cd
. C'est le répertoire courant du shell qui est modifié par
-cd
, ce qui signifie que le script suivant :
+Certaines commandes du shell ne sont pas des programmes mais des
+commandes internes (builtins functions). Comme nous
+l'avons vu, elles sont directement reconnues et exécutées par le shell.
+Un exemple de commande interne est cd
; elle modifie
+le répertoire courant du shell.
+Attention : si vous créez un script (c'est-à-dire un programme
+écrit en langage shell) qui utilise cd
, il ne modifie pas
+le répertoire courant du shell qui lance ce script, mais celui d'un
+shell qui est créé à l'occasion de l'exécution de ce script, et qui
+meurt à la fin de cette exécution.
Exemple : je crée un script aller
qui contient les
+lignes suivantes :
#! /bin/sh cd $*-
-ne marche pas, car le shell lance un autre shell pour exécuter le script. -C'est ce sous-shell qui change son répertoire courant, et ce changement est -perdu quand le sous-shell meurt. +
+Nous aurons alors :
++chaland ~ $ aller toto +chaland ~ $ cd toto +chaland ~/toto $+ +
-Scripts pour automatiser ou systématiser des tâches, -opérations un peu compliquées. -
- --sh : .profile (shell de login) ; sh lance un autre shell qui prend la relève -pour la session. -.xinitrc (pour lancer X) +La répétition de commandes complexes en ligne de commande du shell est +rapidement fastidieuse ; aussi est-il très pratique de connaître +les bases de la programmation de scripts shell. Les scripts servent à +automatiser ou systématiser des tâches.
@@ -90,9 +187,22 @@ config conscrits. Il est n options.
+ Il existe encore le script .xinitrc
, qui lance X ;
+X est le gestionnaire de fenêtres classique sous Unix.
+
+Le nombre de scripts possibles est illimité ; vous pouvez en créer +autant que vous voulez, selon vos besoins : c'est ainsi que l'on +personnalise son système et qu'on l'adapte à ses exigences, plutôt que +l'inverse. +
+ +Il est parfois ennuyeux d'avoir à taper un nom complet de fichier comme @@ -107,13 +217,13 @@ Pour (wildcards en anglais).
-
Une étoile *
dans un nom de fichier est
interprétée par le shell comme « n'importe quelle séquence de
caractères » (mais ça ignore les fichiers dont le nom commence par un
-point). Exemple:
+point). Exemple :
cc -o foo *.c@@ -128,7 +238,7 @@ ex
cc -o foo bar.c buz.c foo.c gee.c gog.c-
On a aussi le point d'interrogation ?
, qui
@@ -137,7 +247,7 @@ de nom). Par exemple, ls *.?
liste tous les dont l'extension
ne comporte qu'un caractère (.c
, .h
...).
La forme [abcd]
remplace un caractère quelconque parmi
@@ -208,7 +318,7 @@ backslash est lui-m
-Exemples: +Exemples :
@@ -221,20 +331,21 @@ Exemples:Un autre moyen est d'inclure une chaîne de caractères entre apostrophes -(simples quotes)
'
. Tout ce qui se trouve entre deux apostrophes -sera passé tel quel par le shell à la commande. -Exemple: +(simples quotes)'
. Tout ce qui se trouve entre deux +apostrophes sera passé tel quel par le shell à la +commande. Exemple :chaland ~ $ echo '$?*' $?*
-Les guillemets doubles ou doubles quotes (
+"
)Les guillemets doubles ou doubles quotes (
-"
)+
Les guillemets se comportent comme les apostrophes, à une exception près: les -dollars et les backslashes sont interprétés entre les guillemets. Exemple: +dollars et les backslashes sont interprétés entre les guillemets. +Exemple :
@@ -242,8 +353,9 @@ dollars et les backslashes sont interpr /users/87/maths/doligez/*-Une technique utile: Quand on juxtapose deux chaînes de caractères quotées, le -shell les concatène, et elles ne forment qu'un argument. Exemple: +Une technique utile: Quand on juxtapose deux chaînes de caractères +quotées, le shell les concatène, et elles ne forment qu'un argument. +Exemple :
@@ -263,7 +375,7 @@ de savoir si Dernière forme de quotation:`commande`
. Le shell exécute la commande indiquée entre backquotes, lit la sortie de la commande mot par mot, et remplace`
commande -`
par la liste de ces mots. Exemple : +`
par la liste de ces mots. Exemple :@@ -284,20 +396,92 @@ commande it cmd /usr/local/bin/emacs-Redirections
+Entrée, sortie et redirection
+ +Entrée et sortie
-Chaque commande a une entrée standard, une sortie standard, -et une sortie d'erreur. Par défaut, l'entrée standard est le clavier, -la sortie standard est l'écran, et la sortie d'erreur est aussi l'écran. +Un programme consiste à traiter des données, et à renvoyer des données +transformées : il transforme des informations, et c'est pourquoi +l'on parle d'informatique.
+ +Prenons le programme
+hachoir
, par exemple : on y +fait entrer des choses, elles sortent sous une autre forme, et dans +l'intervalle, elles subissent des transformations régulières. Par +exemple, on fait entrer une vache, il en ressort du steak haché ; +on y fait entrer des carottes, il en ressort des carottes rapées.+Deux concepts permettent de modéliser cette transformation +d'informations : les concepts d'entrée et de +sortie. L'entrée, c'est la vache ou les carottes ; +la sortie, c'est le steak haché ou les carottes +rapées. +
+ +Sortie standard et sortie d'erreur
+ ++Mais cette première distinction entre entrée et sortie ne suffit pas, +car la sortie d'un programme, c'est-à-dire les messages qu'il renvoie, +sont de deux ordres : il y a les messages normaux relevant +de la transformation d'informations (par exemple le steak haché ou les +carottes rapées), mais il y a aussi des messages d'erreur.
+ +Par exemple, si vous mettez, sur le tapis roulant qui mène au +hachoir, un objet trop gros pour y rentrer, le hachoir, s'il est bien +conçu, devra vous prévenir qu'il n'arrive pas à hacher un objet si +gros. Et ce message, quoiqu'il sorte aussi bien du hachoir que le steak +haché, ne doit pas être traité de la même façon à sa sortie, et n'est +pas suivi des mêmes conséquences. C'est pourquoi l'on distingue la +sortie standard et la sortie d'erreur. +
+ ++Pour résumer, chaque commande a donc :
+
Par défaut, l'entrée standard est le clavier, la sortie standard est +l'écran, et la sortie d'erreur est aussi l'écran.
+ +C'est sur le clavier que vous tapez ; ce que vous tapez et ce +que renvoient les programmes s'inscrit à l'écran ; les messages +d'erreur renvoyés par les programmes s'affichent à l'écran. +
+ ++Mais il ne s'agit là que du comportement par défaut, et pas d'un +comportement obligatoire. Vous pouvez tout à fait orienter différemment +vos programmes.
+ +Par exemple, si vous donnez une vache comme entrée au hachoir, vous +pouvez orienter la sortie vers une imprimante (au lieu de l'écran, +proposé par défaut), et vous imprimerez ainsi du steak haché.
+ +
+Ou encore, vous pouvez donner un plant de carottes comme entrée au
+programme cueillette
, et envoyer la sortie (c'est-à-dire
+les carottes cueillies) au programme hachoir
.
+
>
-On peut rediriger la sortie standard d'une commande vers un fichier
-(caractère >
). Le résultat de la commande sera placé dans le
-fichier au lieu de s'afficher sur l'écran. Exemple:
+On peut rediriger la sortie standard d'une commande vers un
+fichier (caractère « >
»). Le résultat de la
+commande sera placé dans le fichier au lieu de s'afficher sur l'écran.
+Exemple :
chaland ~ $ ls -l > foo
@@ -314,12 +498,41 @@ dans le fichier foo
. On peut alors taper
pour lire le fichier page par page.
+
+>>
On veut parfois ajouter la sortie d'un programme à un fichier, sans +effacer ce qui précède. Or, par défaut, si l'on tape plusieurs fois +
+ +chaland ~ $ ls -l > foo
+
+
+à chaque fois, le contenu antérieur du fichier foo
est
+écrasé par le contenu ultérieur.
+
+Pour éviter cela, il existe l'outil de redirection >>. Ainsi, si +vous tapez plusieurs fois +
+ +chaland ~ $ ls -l >> foo
+
+
+le fichier foo
contiendra à la suite tout ce que
+vous a renvoyé la commande.
+
<
On peut aussi rediriger l'entrée standard d'une commande (caractère
-<
). La commande lira alors le fichier au lieu du clavier.
-Exemple:
+« <
»). La commande lira alors le fichier au
+lieu du clavier. Exemple :
chaland ~ $ elm leroy < foo
@@ -339,19 +552,64 @@ standard et l'affiche page par page sur le terminal.
|
-On peut se passer du fichier intermédiaire grâce à un pipe
-(caractère |
). Un pipe connecte directement la sortie standard d'une
-commande sur l'entrée standard d'une autre commande. Exemple: pour afficher
-page par page la liste des fichiers du répertoire courant, faire
+Il devient rapidement ennuyeux de taper :
+
chaland ~ $ ls -l > foo +chaland ~ $ less < foo +chaland ~ $ rm foo+ +
+On peut se passer du fichier intermédiaire (foo
dans notre
+exemple) grâce à un pipe (caractère
+« |
»). Un pipe connecte directement la sortie
+standard d'une commande sur l'entrée standard d'une autre commande.
+Exemple : pour afficher page par page la liste des fichiers du
+répertoire courant, faire
chaland ~ $ ls -l | less
-Le pipe est d'un usage très courant et rend beaucoup de services. +Le pipe, ou tube, est d'un usage très courant, et rend beaucoup de +services.
-
+On a parfois besoin de savoir si une commande a réussi ou non avant d'en
+lancer une autre. Les indicateurs &&
et
+||
permettent, respectivement, de lancer une commande si
+(et seulement si) la précédente a réussi ou échoué.
+
+Par exemple, si j'ai un fichier foo
, j'obtiens :
+
+chaland ~ $ ls foo && echo "J'ai un fichier foo."
+foo
+J'ai un fichier foo.
+
+
+
+Si je n'ai pas de fichier foo
, le message ne s'affiche
+pas. En revanche, si je tape alors :
+
+chaland ~ $ ls foo || echo "Je n'ai pas de fichier foo."
+ls: foo: No such file or directory
+Je n'ai pas de fichier foo.
+
+
+
+
+La panoplie complète des redirections est la suivante (le tableau indique les @@ -379,11 +637,19 @@ premi +
+Il est parfois utile de rediriger la sortie standard et la sortie
+d'erreur vers un même endroit. Pour cela, on utilise le motif
+2>&1
avant la redirection.
+
Fonction | -Bourne shell | -Z-shell | +Bourne shell (sh, bash) | +Z-shell (zsh) |
---|---|---|---|---|
Redirige la sortie d'erreur (2) et la sortie standard (1) sur l'entrée
@@ -472,12 +738,79 @@ Affiche les 10 derniers mots du dictionnaire qui contiennent la cha
Variables+Qu'est-ce qu'une variable ?+
-Le shell a des variables. Pour désigner le contenu d'une variable, on écrit
-le nom de la variable précédé d'un dollar. Exemple: +La notion de variable est commune à presque tous les langages +informatiques, et en particulier aux langages de programmation. Ceux qui +ont déjà manipulé des langages sont donc familiers avec cette +notion. Pour les autres, un petit exemple les aidera peut-être à la +saisir. ++Mettons que vous programmiez le hachoir dont nous parlions plus haut. Un +hachoir est un instrument dangereux, à ne pas mettre à la portée des +enfants. Robert le jardinier, qui a conçu ce hachoir, veut être le seul +à pouvoir l'utiliser, sans quoi le petit Émile pourrait se blesser en y +mettant le doigt. + + Ainsi, il va dire au programme
+Certaines variables sont prédéfinies, par exemple
+ Les variables en shell+ +
+En shell, pour désigner le contenu d'une variable, on écrit le nom de la
+variable précédé du signe dollar. Exemple : Les noms de variables+ +
+Par convention, les variables relevant du système, comme
+
+Les noms de variables sont en effet sensibles à la casse :
+ Définir une variable+
La façon de donner une valeur à une variable varie selon le type de shell
utilisé :
@@ -504,11 +837,14 @@ Famille des Bourne Shell ( Les variables d'environnement+
-Les valeurs des variables sont accessibles aux commandes lancées par le shell.
-L'ensemble de ces valeurs constitue l'environnement. On peut aussi
-supprimer une variable de l'environnement avec @@ -516,30 +852,24 @@ Quelques variables d'environnement:
@@ -559,75 +889,173 @@ nous avons d
-Pour la programmation du shell, nous allons utiliser le shell sh , qui est le plus répandu et standard. Ce que nous avons
+vu jusqu'ici s'applique aussi bien à sh qu'à
+zsh et aussi à csh , à l'exception de
+setenv et de certaines redirections signalées.
+
+
+Rendre un script exécutable+ +Pour être un script, un fichier doit commencer par la ligne: #!/bin/sh
Il doit aussi avoir être exécutable (bit chaland ~ chmod u+x fichier
+
+
++(pour en savoir plus sur les droits attachés à un fichier, consultez la +page sur les droits d'accès). + + +Structures de contrôle- -for- -for var in liste de chaînes ; -do commandes ; done+ +C'est avec les structures de contrôle qu'un programme peut commencer à +devenir sérieux. Le principe général de ces structures est le +suivant : adapter le comportement du programme selon les réponses +apportées à certaines questions. +
-Affecte successivement à la variable de nom var chaque chaîne de
-caractères trouvée dans la liste de chaînes, et exécute les
-commandes une fois pour chaque chaîne.
+Nous avons déjà vu une application possible des structures de contrôle
+en parlant des variables. Le programme
La boucle
+
+ |