1.1 : Introduction

cours:commencez ici

Unix est un système d'exploitation créé en 1970.

C'est le premier système d'exploitation à avoir été écrit dans un langage évolué : le langage C.

Il est maintenant présent partout : téléphone, box internet, appareil photo, routeur, télévision, lecteur blu-ray, disque réseau et même certains aspirateurs. En 2014, 498 des 500 ordinateurs les plus puissants du monde utilisaient Unix.

Ce cours va vous permettre d'utiliser Unix de manière efficace en utilisant un langage textuel pour lui donner des ordres plutôt qu'en utilisant la souris qui ne permet pas de communiquer aussi rapidement.


cours:à quoi ça sert

Le système d'exploitation (operating system) permet de cacher (s'abstraire de) la partie matérielle (le hardware) afin de pouvoir faire fonctionner les programmes indépendamment de l'ordinateur utilisé.

Il partage les ressources matérielles (processeur, mémoire vive, disque...) entre les différentes tâches qui s'exécutent et gère les autorisations d'accès.


cours:fichier

Les systèmes d'exploitation permettent de stocker l'information dans des fichiers (files) qui sont des suites d'octets (bytes).

Un octet est composé de 8 bits (un bit vaut 0 ou 1). Il permet de représenter 28 = 256 valeurs différentes.

Certain fichiers nécessitent d'être affichés en utilisant une application (les images et les fichiers PDF par exemple). D'autres sont directement lisibles et modifiables par un être humain, c'est le cas du code source des langages de programmation, du HTML, du CSS...

Les fichiers sont généralement mémorisés sur un support de stockage persistant (disque dur, clef USB...) ce qui permet de les retrouver quand l'ordinateur redémarre.


cours:répertoire

Les systèmes d'exploitation permettent d'organiser les fichiers en les rangeant dans des répertoires (directory en anglais) qui eux mêmes peuvent être rangés dans d'autres répertoires.

Dans le monde Windows, on appelle les répertoires des dossiers (folder en anglais).

Pour retrouver le fichier dans le répertoire, on lui donne un nom sous la forme d'une suite d'octets. Sous Unix, le nom ne doit pas :

Dans la suite du texte, les chaines de caractères représentant un nom de fichier seront représentées de cette façon : UnNomDeFichier, x, /tmp.

Attention : TOTO et Toto ne sont pas le même nom de fichier car un lettre majuscule est différente de son équivalent en minuscule. Néanmoins l'Unix de Mac OS considère que c'est le même fichier.

1.1.1 : Droits d'accès

cours:login

Pour que le système d'exploitation vous permette d'accéder à vos fichiers, il doit savoir qui vous êtes. Il faut donc vous identifier avec un login qui est votre nom d'utilisateur et un mot de passe (password) que vous devez être seul à connaître.

Votre mot de passe doit comporter plus de 12 caractères et doit contenir des caractères non alphanumériques.

Ne faites pas vos TP (programmation, web...) en tant que super utilisateur (root) car il est très facile de casser sa machine. Les questions de ce TP présupposent que vous êtes un utilisateur normal.

1.1.2 : Chemin

cours:chemin absolu

L'ensemble des fichiers et répertoires s'appelle un système de fichiers (file system) et on le représente comme un graphe orienté. Les noeuds sont les entités (fichier, répertoire...) et les noms des entités sont sur les arcs.

La racine (root) est un répertoire à partir duquel on peut accéder à l'ensemble des fichiers et répertoires du système de fichiers. Le chemin vers la racine s'écrit /

Un chemin absolu (absolute path) indique la suite d'arcs à suivre dans le graphe pour aller de la racine jusqu'au fichier ou répertoire que l'on veut désigner.

Pour se déplacer le long d'un arc du graphe, il suffit d'ajouter /nom au chemin absolu menant au répertoire ou l'on se trouve.

Le chemin //usr///include est autorisé et représente la même chose que /usr/include afin de simplifier les algorithmes. C'est possible, car le nom de fichier vide est interdit.


cours:rép. de connexion

Dans le système de fichiers, chaque utilisateur dispose d'un emplacement qui lui est propre, c'est son répertoire de connexion (home directory) où se trouve tous ses fichiers.

Quand on lance un nouveau shell, le répertoire courant initial est le répertoire de connexion (jusqu'à ce que l'utilisateur se déplace).

Quand on tape la commande cd sans argument, elle supposera que vous voulez aller dans votre répertoire de connexion. C'est en effet le répertoire dans lequel l'utilisateur a le plus souvent besoin d'aller.


cours:chemin relatif

Un chemin relatif (relative path) est un chemin qui part du répertoire courant (indiqué par la commande pwd) et qui indique la suite des arcs à suivre pour arriver au fichier ou dossier que vous voulez nommer.

On reconnait le chemin relatif car il ne commence pas par un /.


cours:. et ..

Chaque répertoire contient 2 répertoires nommés . et ..

Le chemin . représente toujours le répertoire courant et le chemin .. le père de celui-ci.


cours:complétion

Les chemins sont longs à taper et il est facile de faire des erreurs de saisie. Pour résoudre ces problèmes, le shell permet de faire de la complétion.

Quand vous appuyez sur la touche tabulation (⇥), le shell complète le chemin que vous êtes en train de taper.

Ce qui est mis en évidence est ce qui s'ajoute à la ligne de commande.
Vous tapezIl affiche 
ls /e⇥ ls /etc/ le shell ajoute / à la fin pour indiquer que c'est un répertoire.
ls /etc/ba ls /etc/bash♪ le shell fait un bip (♪) pour vous indiquer que l'on peut encore compléter.
ls /etc/bash ls /etc/bash le shell fait un bip pour indiquer qu'il y a plusieurs suites possibles.
ls /etc/bash bash.bashrc bash_completion bash_completion.d/ le shell donne la liste des suites possibles afin que vous puissiez taper la suite du nom du fichier.
ls /etc/bash_⇥ ls /etc/bash_completion♪ le shell fait un bip (♪) car il y a une suite possible.
ls /etc/bash.⇥ ls /etc/bash.bashrc   Le shell ajoute ajoute un espace pour indiquer que le nom du fichier est complet
Attention, dans beaucoup de configuration par défaut le bip est désactivé.


cours:maison

Quand le shell trouve un chemin qui commence par tilde (~), il le remplace par le chemin absolu menant au répertoire de connexion s'il existe :
Vous tapezCela devient peut-être
~ /home/votre_login
~/ /home/votre_login/
~toto /home/t/toto
~toto//home/t/toto/


cours:liens

Sous Unix il y a des liens physiques (hard link) et des liens symboliques (symbolic link).

Le lien physique permet de mettre le même fichier à plusieurs endroits dans le système de fichiers. Il est déconseillé de créer des liens physiques, car les applications ne les traitent pas correctement. Néanmoins, le système en utilise beaucoup, par exemple les chemins /usr, /usr/., /usr/include/.., représentent le même répertoire, mais situé à différents endroits dans la hiérarchie.

Le lien symbolique contient une chaine de caractères qui est un chemin absolu ou relatif vers un fichier ou un répertoire. C'est comme un raccourci sous Windows. Le chemin relatif l'est par rapport à l'endroit où se trouve le lien. Les applications utilisent l'entité pointée par le lien de manière complètement transparente, elles n'ont pas besoin d'être prévues pour. Attention : si vous détruisez la chose pointée, le lien existe toujours mais n'est plus utilisable ; inversement, si vous détruisez le lien, la chose pointée n'est pas détruite.

Pour voir vers quoi pointent les liens, il suffit de lancer la commande ls -l qui sera expliquée plus tard.

Exemple d'utilisation dans la distribution Debian : /bin/sh est un lien symbolique vers dash; ceci permet de changer l'application associée à /bin/sh sans avoir besoin de faire une copie qui deviendrait obsolète si /bin/dash était mis à jour.


cours:organisation

Sur les systèmes Unix on retrouve toujours certains répertoires. En voici quelques-uns parmi les plus importants :
CheminContenu
/home Les répertoires de connexion des utilisateurs.
/bin et
/usr/bin
Les commandes Unix.
/etc Les fichiers de configuration d'Unix.
/tmp Les fichiers temporaires, ils sont effacés quand la machine est relancée. Normalement, l'accès à ces fichiers est plus rapide que l'accès des fichiers qui sont sur votre compte.
/var Les données des applications utilisées par le système lui même (pas celles des utilisateurs). /var/log contient les fichiers notant tous les événements importants qui se sont passés dans le système.

1.1.3 : Shell

cours:shell

L'interface pour travailler sous Unix est le shell, il en existe de nombreuses sortes. Celui qui va être utilisé est le Bourne shell (1977).

C'est un interpréteur de commandes ; vous lui donnez des ordres sous une forme textuelle dans son langage.

Quand vous avez accès à une machine sous Unix, pour avoir accès à un shell, vous pouvez le lancer en :

Une console est un dispositif physique (TTY) ou virtuel (VTY) qui envoie à une application ce qui est tapé au clavier et qui affiche ce que l'application écrit.

Un terminal est simplement une application qui simule une console texte sur l'écran graphique. Par défaut l'application liée à cette console virtuelle est le shell.

Le shell est long à apprendre et à maîtriser mais il permet de travailler bien plus efficacement qu'avec la souris.


cours:prompt

Le shell vous indique qu'il attend vos ordres en affichant une invite de commande (prompt en anglais).

Pour lancer une commande : vous la tapez puis appuyez sur la touche Entrée pour dire au shell de la lancer.

Un nouveau prompt sera affiché quand la commande sera terminée.

Si la commande prend du temps pour se terminer, cela ne vous empêche pas de commencer à taper la prochaine commande qui sera lancée quand la précédente sera terminée.

Si vous ne tapez rien et appuyez simplement sur la touche Entrée un nouveau prompt apparaîtra immédiatement sur la ligne suivante lorsque la commande précédente est terminée.


cours:exit

Pour quitter le shell, il y a plusieurs méthodes :


cours:édition commande

Il est facile de se tromper en tapant une commande. Pour corriger une saisie, on peut utiliser les touches curseur gauche/droite, début/fin ligne pour se déplacer dans la ligne et modifier le texte.

On peut aussi utiliser la touche curseur haut/bas pour rappeler et éditer les commandes précédentes.

On peut taper sur la touche Entrée pour lancer la commande même si l'on n'est pas à la fin de la ligne.


cours:Ctrl+C

Parfois on lance une commande qui bloque ou qui prend trop de temps. Il est très facile d'arrêter la commande en tuant le processus, il suffit de taper Ctrl+C au clavier. Il ne sera pas possible de reprendre son exécution à l'endroit où elle a été interrompue.


cours:lecture clavier

Beaucoup de commandes traitant des informations qui sont dans des fichiers, vont traiter ce qui est tapé au clavier si on les lance sans leur indiquer de nom de fichier en paramètre (par exemple sort, cat, uniq, wc, tail).

Remarques :

Ceci permet de traiter des données sans avoir besoin de les stocker dans des fichiers.


cours:historique

Il faut parfois utiliser la touche «flèche vers le haut» de très nombreuses fois pour retrouver une commande tapée il y a longtemps. On peut heureusement lancer une recherche de commande en tapant Ctrl+R suivi d'un mot clef ('R' pour reverse). Pour remonter plus en arrière dans le passé, on retape simplement Ctrl+R autant de fois que nécessaire.

Quand on a trouvé la bonne commande, on peut taper Entrée pour la réexécuter ou bien utiliser les touches curseur pour la modifier.

C'est une fonctionnalité de bash qui n'existe pas dans /bin/sh qui est le shell standard, mais que personne n'utilise de manière interactive. Ce raccourci clavier de bash, comme beaucoup d'autres, est le même que dans Emacs.

1.1.4 : Remarques

cours:copier coller

Unix supporte le copier coller de Window avec Ctrl+C et Ctrl+V dans presque toutes les applications.

Mais dans le shell Ctrl+C et Ctrl+V ont d'autres significations, il faut taper à la place Maj+Ctrl+C et Maj+Ctrl+V ce qui est très lourd (et ne fonctionne pas avec Putty).

La version native du copier coller sous Unix est bien plus efficace, elle fonctionne dans presque toutes les applications :

La sélection d'un mot peut se faire en double-cliquant sur le mot.
La sélection de l'ensemble d'une ligne peut se faire en triple-cliquant n'importe où sur la ligne.


cours:scroll

Quand trop de choses s'affichent sur l'écran, le texte monte et disparaît en haut. On peut utiliser la barre de défilement (l'ascenseur) pour voir ce qui a disparu, mais cela nécessite de lâcher le clavier ce qui prend du temps. On peut déplacer l'ascenseur en utilisant les commandes suivantes au clavier :

1.1.5 : Essayer

cours:accéder au shell

Pour vous entrainer à utiliser Unix, il faut que vous puissiez y avoir accès. Pour cela de nombreuses méthodes sont possibles :

1.2 : Commandes

1.2.1 : Navigation

cours:pwd

La commande pwd (Print Working Directory) indique le chemin absolu (path) vers l'endroit où vous vous trouvez.

C'est le répertoire courant (current directory) de votre shell.


cours:cd «base:se déplacer» «base:déplace relatif 2»

La commande cd (Change Directory) permet de se déplacer dans le système de fichiers en changeant le répertoire courant du shell. Après avoir tapé la commande cd /usr/bin votre répertoire courant sera le répertoire bin qui est dans le répertoire usr qui se trouve à la racine du système de fichiers.

Les mots qui suivent le nom de la commande sont appelés des arguments et ils sont séparés par un ou plusieurs espaces.


cours:mkdir «base:créer distant»

La commande mkdir (make directory) permet de créer un ou plusieurs répertoires vides.

La commande mkdir XTRUC /tmp/machin va créer les répertoires :


cours:ls

La commande Unix ls permet d'afficher la liste des noms des entités (fichiers ou répertoires) contenues dans les répertoires indiqués.
ls Le contenu du répertoire courant.
C'est la même chose que ls . mais en plus rapide à taper au clavier.
ls /etc Le contenu du répertoire /etc (répertoire etc à la racine).
ls Documents Le contenu du répertoire Documents se trouvant dans le répertoire courant.
C'est la même chose que ls ./Documents.
ls .. Le contenu du père du répertoire courant.
ls /etc/profile Le texte : /etc/profile car c'est un nom de fichier, pas un nom de répertoire.
Cela n'affiche pas le contenu du fichier, seulement son nom.
ls /etc /bin /usr Le contenu successif des trois répertoires.


cours:fichier caché

Quand vous lancez la commande ls, elle affiche le contenu du répertoire courant, mais on ne trouve pas . et .. dans la liste des fichiers alors qu'ils existent.

C'est pour ne pas encombrer l'utilisateur avec ces fichiers qui existent dans tous les répertoires, et n'apportent donc aucune information et perdent de la place sur l'écran.

Les fichiers cachés sont les fichiers dont le nom commence par le caractère ..


cours:options

Les options sont des arguments qui permettent de modifier le comportement de la commande. Les options courtes sont sur une seule lettre, les options longues peuvent contenir plusieurs lettres.

Les règles concernant les options sont les suivantes :

Les commandes ls suivantes s'exécutent toutes exactement de la même façon :
ls --all -l /tmp Affiche le contenu du répertoire /tmp en tenant compte de l'option longue --all qui permet d'afficher les fichiers cachés et de l'option courte -l qui permet d'afficher plus d'information (-l pour long)
ls -a -l /tmp car -a--all
ls -al /tmp car on peut concaténer les options courtes
ls -la /tmp car pour ls l'ordre des options n'a pas d'importance car elles ne sont pas paramétrées.


cours:ln

La commande ln (link) permet de créer des liens.

La syntaxe de la commande ln est la même que celle des commandes cp et mv : on indique le nom du fichier vers lequel on pointera et le nom du fichier que l'on veut créer. Si le lien symbolique pointe sur un chemin relatif, c'est par rapport au répertoire contenant le lien symbolique.

ln -s a b va créer le lien b qui pointera sur a. L'entité a peut très bien ne pas exister. Il n'y aura pas de message d'erreur.

Comme les deux autres commandes, elle peut créer plusieurs fichiers si la destination est un répertoire. Dans ce cas, le nom du fichier créé est le nom du fichier original.

1.2.2 : Contenu des fichiers

cours:cat «base:afficher distant»

La commande cat (concat) permet d'afficher bout à bout (de concaténer) le contenu de plusieurs fichiers sur l'écran.


cours:cp «base:copie»

La commande cp (copy) permet de copier des fichiers et des hiérarchies de fichiers.

Le copie la plus simple est cp a b
chemin a chemin b Résultat
fichier n'existe pas b est créé et c'est une copie de a
fichier fichier b est écrasé par la copie de a
fichier répertoire b/a est créé ou écrasé s'il existe déjà et c'est une copie de a
n'existe pas une erreur
répertoire une erreur car sans option la commande cp copie seulement des fichiers


cours:cp multiple

La commande cp peut copier plusieurs fichiers en même temps : cp chemin1/f1 chemin2/f2... destination


cours:cp récursif «base:copier distant»

La commande cp peut copier des répertoires ainsi que leur contenu. Mais il faut indiquer l'option indiquant la récursion : en version courte -r ou en version longue --recursive.


cours:less

La commande less permet d'afficher page par page le contenu d'un ou plusieurs fichiers dont les noms sont passés en argument. Contrairement aux commandes précédentes qui font leur travail et se terminent, celle-ci est interactive et ne se termine pas, car elle attend des instructions de l'utilisateur. Celui-ci tape les instructions au clavier, voici les principales instructions :

Si la commande less n'existe pas, vous pouvez utiliser la commande standard more, mais elle est moins puissante.


cours:tail

Pour voir la fin d'un fichier sans l'afficher en entier, il est possible de lancer la commande less et d'aller à la fin (en appuyant sur la touche Fin du clavier). Mais il est plus simple d'utiliser la commande tail qui affiche directement les dernières lignes d'un ou plusieurs fichiers.


cours:rm «base:destruction» «base:destruction idiote»

La commande rm (remove) permet de détruire les fichiers dont les chemins sont passés en paramètre.

Pour détruire des répertoires et leurs contenus, il faut ajouter l'option -r.

ATTENTION, dans un Unix standard qui n'a pas été amélioré :


cours:mv

La commande mv (move) permet de déplacer un fichier :

Exécuter la commande mv f1 d1 DIR équivaut à exécuter l'une après l'autre les commandes :

La commande mv est plus courte : donc plus rapide à taper et avec moins de risques d'erreur. Si l'origine et la destination sont sur le même système de fichiers, ce qui est le cas le plus courant :

L'inconvénient est que si l'origine et la destination ne sont pas sur le même disque, alors on peut se retrouver avec la moitié des fichiers déplacés s'il y a une coupure de courant...


cours:diff

La commande diff (différences) affiche les différences entre 2 fichiers texte. Elle affiche les lignes qui ont été ajoutées (préfixées par > ou +) et enlevées (préfixées par < ou -) pour passer de la première à la deuxième version. L'option -u permet d'afficher quelques lignes autour des modifications afin d'avoir des éléments de contexte.

v1.txt v2.txt diff v1.txt v2.txt diff -u v1.txt v2.txt
un mot
deux mot
trois mots
cinq mots
six mots
six mots
sept mots
un mot
deux mots
trois mots
quatre mots
cinq mots
six mots
sept mots
2c2
< deux mot
---
> deux mots
3a4
> quatre mots
5d5
< six mots
--- v1.txt 2016-03-04 09:45:35 +0100
+++ v2.txt 2016-03-04 10:35:04 +0100
@@ -1,8 +1,7 @@
 un mot
-deux mot
+deux mots
 trois mots
+quatre mots
 cinq mots
 six mots
-six mots
 sept mots

1.2.3 : Outils

cours:man «base:rm tranquille»

La commande man permet de lire les manuels. Elle vous permet d'avoir toutes les informations sur les commandes Unix. Pour voir le manuel, il suffit de taper man nom_de_la_commande, par exemple man cp. C'est une commande interactive qui se terminera lorsque vous la quitterez ; l'affichage du manuel est automatiquement fait page par page en utilisant la commande less (vous n'avez pas besoin de la lancer).

Les manuels affichés sont ceux des commandes installées sur votre machine. Ce n'est pas forcément le cas des manuels que vous trouvez sur Internet.

Pour en savoir plus sur la commande man, lancez man man.


cours:df

La commande df (disk free) permet de lister les systèmes de fichiers utilisables en indiquant :

Les tailles indiquées sont en nombre de blocs disques et la taille de ceux-ci dépend du système de fichiers.

Si vous êtes restreint par des quotas d'utilisation du disque, vous pourrez ne pas profiter de tout l'espace libre.


cours:sort

La commande sort permet de lire des fichiers et de les afficher en triant l'ensemble des lignes dans l'ordre alphabétique.
Contenu du fichierTri anglaisTri français
2
11
Jean
Jean's
Jeanne
Jean Pierre
Jean-Pierre
Jean-Jacques
11
2
Jean
Jean Pierre
Jean's
Jean-Jacques
Jean-Pierre
Jeanne
11
2
Jean
Jean-Jacques
Jeanne
Jean Pierre
Jean-Pierre
Jean's
Attention les logiciels ne trient pas tous de la même façon. Par exemple, Excel sur Windows ou sur Mac ne donnent pas le même ordre.

Pour trier des nombres dans le bon ordre (11 après 2) il faut mettre l'option -n


cours:wc

La commande wc (word count) affiche le nombre de lignes, mots et octets contenus dans les fichiers dont les noms sont indiqués.


cours:uniq

La commande uniq affiche les lignes des fichiers en remplaçant les suites de lignes identiques par une seule ligne.


cours:du

La commande du (disk usage) permet d'afficher la place occupée en nombre de blocs disques par une hiérarchie de fichiers.
du /etc ~/Documents Place occupée par chacun des répertoires dans les hiérarchies /etc et Documents dans votre répertoire de connexion.
du Sans nom de répertoire, il fait du .
du -h ou du --human-readable Affiche la place occupée en Kilo, Méga, Giga... octets.
du -s ou du --summarize Affiche la place occupée par le répertoire indiqué, les tailles des sous-répertoires sont sommées mais ne sont pas affichées.


cours:date

La commande date permet de manipuler les dates et les heures. Ce qui suit n'est pas à apprendre par coeur, mais il faut connaître les possibilités :


cours:tar

La commande tar (tape archiving) permet de transformer une hiérarchie de fichiers en un seul fichier au format tar. Elle permet aussi d'extraire l'archive.

C'est utile pour :

Les commandes les plus courantes sont :

Remarques :


cours:gzip

La commande gzip (GNU zip) permet de compresser des fichiers pour qu'ils prennent moins de place disque.

gzip toto va créer un fichier toto.gz et détruire le fichier toto.

Remarques :

Pour transformer une hiérarchie en un seul fichier, on crée un fichier xxx.tar puis on le compresse. Parfois les gens renomment le fichier xxx.tar.gz en xxx.tgz pour que le nom ne comporte qu'un seul point.


cours:gunzip

La commande gunzip (GNU unzip) permet de décompresser des fichiers d'extension .gz.

gunzip toto.gz va créer un fichier toto et détruire le fichier toto.gz

Remarques :


cours:zcat «theme:intro»

La commande zcat prend comme paramètre des fichiers compressés et les affiche décompressés.

zcat toto.gz affiche le fichier non compressé, sans modifier toto.gz ni créer toto sur le disque.


cours:sleep

La commande sleep prend en paramètre un nombre de secondes. Elle attend ce nombre de secondes avant de se terminer. Ceci permet d'attendre avant d'exécuter la commande suivante.


cours:apropos

Parfois on cherche une commande sans connaître son nom. Par exemple pour lister toutes les commandes ayant un rapport avec le mot cos, la syntaxe est man -k cos.

2.1 : Introduction

cours:commencez ici

Ce module présente comment utiliser des variables, manipuler de nombreux fichiers avec les pattern, protéger les caractères spéciaux et faire des boucles.

2.2 : Builtins du shell

cours:builtins

Les builtins (fonctions intégrées), ne sont pas des commandes Unix mais des commandes du shell.

Voici la liste dans l'ordre alphabétique des commandes et builtins vues dans le module numéro 1.
CommandeChemin où l'on trouve la commande
cat /bin/cat
cd builtin
cp /bin/cp
date /bin/date
df /bin/df
diff /usr/bin/diff
du /usr/bin/du
exit builtin
gunzip /bin/gunzip
gzip /bin/gzip
less /usr/bin/less
ln /bin/ln
ls /bin/ls
man /usr/bin/man
mkdir /bin/mkdir
mv /bin/mv
pwd builtin
rm /bin/rm
sleep /bin/sleep
sort /usr/bin/sort
tail /usr/bin/tail
tar /bin/tar
uniq /usr/bin/uniq
wc /usr/bin/wc
zcat /bin/zcat


cours:echo

La commande builtin echo, permet d'afficher ses paramètres sur l'écran.

Lorsqu'elle affiche, elle met un espace entre chacun de ses paramètres et ajoute par défaut un retour à la ligne à la fin.
La commande : echo paramètre1 paramètre2 paramètre3
affiche :
paramètre1 paramètre2 paramètre3

2.3 : Patterns du shell

cours:patterns

Le shell remplace les pattern qui sont dans la ligne de commande par tous les chemins de toutes les entités (fichier, répertoire) qui existent et qui correspondent au pattern. Cette opération s'appelle le globbing.

Si aucune entité n'existe, alors le pattern reste sans modification dans la ligne de commande.

Un pattern est composé d'une série de caractères :

Le pattern toto ne peut évidemment correspondre qu'à la chaîne de caractères toto, car si le fichier n'existe pas le pattern reste inchangé. La commande echo toto affichera donc toujours toto que le fichier existe ou non.


cours:patterns *

Le caractère * est le caractère spécial qui est remplacé par une chaîne de caractères quelconques :

PatternLes chemins que cela représente
a* Les entités du répertoire courant dont le nom commence par a.
*b Les entités visibles du répertoire courant dont le nom finit par b.
c*d Les entités du répertoire courant dont le nom commence par c et finit par d.
*f* Les entités visibles du répertoire courant dont le nom contient f.
*gg*hh* Les entités visibles du répertoire courant dont le nom contient gg puis, plus loin hh.
/etc/i* Les entités contenues dans /etc dont le nom commence par i.
/et*/*.conf Les entités visibles dont le nom finit par .conf et contenues dans les répertoires situés à la racine dont le nom commence par et.
*m/*n Les entités visibles dont le nom finit par n et contenues dans les sous-répertoires visibles du répertoire courant dont le nom finit par m.
* Toutes les entités visibles du répertoire courant.
*/p Toutes les entités nommées p dans les sous-répertoires du répertoire courant.
q/* Toutes les entités visibles contenues dans le répertoire q du répertoire courant.

cours:patterns []

Les crochets [] représentent un unique caractère de la liste indiquée entre les crochets.

Attention, certains caractères devront être échappés pour être utilisés :

PatternLes chemins que cela représente
[abc] Les entités nommées a ou b ou c.
[01][01][01] Les entités dont le nom est composé de 3 chiffres 0 ou 1.
toto.[0123456789][0123456789] Les entités dont le nom commence par toto et dont l'extension est composée de 2 chiffres (ni plus, ni moins).


cours:patterns [-]

Pour éviter d'énumérer des caractères consécutifs, on peut indiquer un intervalle de caractères.

PatternLes chemins que cela représente
[a-z][0-9] Les entités avec un nom de 2 caractères, le premier étant une lettre minuscule et le deuxième un chiffre.
[.:a-z=,0-9*] Les entités avec un nom d'un seul caractère qui est une minuscule, un chiffre ou un caractère parmi .:=,*.
[*.-:] Les entités avec un nom d'une lettre qui est une étoile ou bien dans l'intervalle indiqué : ./0123456789:. Les intervalles sont pris dans l'ordre des caractères ASCII, pour afficher cette table, tapez man ascii.
[-*.:] Les entités avec un nom d'une lettre qui est dans cette liste : -*.:. En effet, le tiret étant en premier, il ne peut définir un intervalle.

La langue de l'interface utilisateur change complètement la liste des caractères trouvés par [a-z] :

Pour la suite du cours, on considèrera toujours la version anglaise.


cours:patterns [!]

Il est parfois plus intéressant de lister les caractères interdits que les caractères autorisés :

PatternLes chemins que cela représente
[!a4] Les entités visibles avec un nom de 1 caractère, n'étant ni a ni 4.
[!a-zA-Z]* Les entités visibles dont le nom ne commence pas par une lettre.
*[!-_.a-zA-Z0-9]* Les entités visibles dont le nom contient un caractère qui n'est pas ``normal´´.


cours:patterns ? «base:début-fin»

Le caractère ? est le caractère spécial qui est remplacé par un unique caractère :

PatternLes chemins que cela représente
? Les entités visibles du répertoire courant dont le nom est un seul caractère.
????? Les entités visibles du répertoire courant dont le nom est long de 5 caractères.
main.? Les entités du répertoire courant dont le nom est main. suivi d'un seul caractère.
/???/. Les répertoires visibles à la racine du système de fichiers dont le nom est long de 3 caractères.

2.4 : Variables d'environnement

cours:variables

Les variables du shell permettent de stocker une chaîne de caractères et de la réutiliser. Contrairement aux fichiers, elles disparaissent quand vous quittez le shell et sont utilisables quel que soit le répertoire courant.

Un nom de variable shell est composé d'une ou plusieurs lettres, de chiffres et du caractère souligné [a-zA-Z0-9_]. Il ne doit pas commencer par un chiffre.

La casse est importante : TOTO et toto représentent deux variables différentes.


cours:variables $

Quand le shell trouve $NOM_VARIABLE il remplace ce texte par le contenu de la variable.

CommandeAction
echo $A Affiche le contenu de la variable A. Si elle n'existe pas, c'est une chaîne de caractères vide.
echo $TOTO$TITI Affiche le contenu de la variable TOTO suivi du contenu de la variable TITI.
echo $TOTOTITI Affiche le contenu de la variable TOTOTITI même si TOTO et TITI sont des variables qui existent.
echo $TOTO.TITI Affiche le contenu de la variable TOTO suivi du texte .TITI car le caractère . ne peut pas faire partie du nom de la variable.
$TOTO TITI Exécute la commande indiquée dans la variable TOTO avec TITI comme paramètre.

Attention : si le caractère espace ou si un pattern est présent dans le contenu de la variable, alors le shell en tient compte. Ceci veut dire que le nombre d'arguments de la commande echo $A dépend du contenu de la variable.


cours:variables =

Pour mettre une valeur dans une variable, il suffit d'écrire : NOM_VARIABLE=VALEUR_VARIABLE

Attention :


cours:variables courantes

Voici les variables les plus courantes que vous aurez besoin d'utiliser :
NomSignification de la variable
HOME Nom de votre répertoire de connexion.
Vous avez le droit de la modifier afin par exemple de tester une commande dans un environnement vierge. Par contre ~/ reste toujours votre répertoire de connexion réel.
PS1 Le texte affiché dans le prompt (invite de commande).
PATH Les chemins des répertoires dans lesquels le shell va chercher les commandes.
Si vous faites PATH="$PATH:$HOME/shell" le shell ira chercher automatiquement les commandes qui sont dans le répertoire shell de votre répertoire de connexion.


cours:remplacement

L'opération de remplacement substitue la notation $(une ligne de commande shell) par ce que la ligne de commande aurait écrit sur l'écran :
Commande Ce qu'elle fait
A=$(date) Stocke la date courante dans la variable A.
A='$(date)' Affecte la chaîne de caractères $(date) à la variable A.
A=$(rm toto && echo OK) Si la destruction a été possible sans erreur, alors cela stocke OK dans la variable A sinon cela la vide.
rm $(cat liste) Détruit les fichiers dont les chemins sont indiqués dans le fichier liste.
rm "$(cat un_nom)" Détruit le fichier dont le chemin est indiqué dans le fichier un_nom. En effet, les guillemets protègent les espaces.
Attention : A=$date affecte le contenu de la variable date à la variable A. La variable date n'étant généralement pas définie, la variable A sera donc vidée.

2.5 : Échappement des caractères spéciaux

cours:échappement \ «base:nom étrange» «base:allez à»

L'échappement (escape) permet d'enlever sa signification particulière à un caractère pour indiquer que l'on veut simplement le caractère lui-même. Pour ce faire, on échappe le caractère en mettant un backslash (barre oblique inversée) devant.

Commande Ce que cela fait
echo \* Affiche une étoile.
cat mon\ projet Le contenu du fichier mon projet. Sans le backslash cela affiche le contenu des fichiers mon et projet.
echo *[\!\;\$\ ] Affiche les entités visibles du répertoire courant se terminant par l'un des caractères !;$ ou bien l'espace.
echo ligne1\ ligne2 Cela affiche le résultat sur deux lignes car le backslash annule la signification du retour à la ligne, le premier argument de la commande echo contient donc ligne1\nligne2, le \n est souvent utilisé en informatique pour représenter le passage à la ligne suivante.

Tapez cette commande dans votre terminal sans faire de copier/coller pour voir ce qu'il se passe quand on tape une commande sur plusieurs lignes.

Attention : mettre un backslash devant un caractère normal peut dans certain cas lui ajouter une signification. Par exemple \n indique une fin de ligne dans beaucoup de langages de programmation.


cours:échappement ' «base:copie horrible» «base:affichage piégé»

Quand il y a beaucoup de caractères à échapper, cela prend du temps pour taper tous les backslashs. Dans ces cas là, on met le texte complet à échapper entre cotes : 'un texte à échapper' est plus facile à taper et plus court que un\ texte\ à\ échapper.

La commandeafficheparce que
echo a b a b echo a 2 arguments, ils sont affichés séparés par un espace lors de l'affichage.
echo 'a b' a b Il y a un seul argument car les espaces sont protégés.
echo '$A * *[a-z]*' $A * *[a-z]* La signification de tous ces caractères est annulée.
echo 'a\ \ \ b' a\ \ \ b Le backslash a perdu sa signification car il est entre cotes.
echo '' La cote n'échappe pas sa propre signification, l'argument est donc une chaîne de caractères vide.
echo '''' Le seul argument est vide car c'est deux chaînes vides l'une à la suite de l'autre.
echo a '' '' b a b echo a 4 arguments, les deux du milieu étant vides. Lorsqu'il affiche ses arguments, il les sépare par un espace, c'est pour cela qu'il y a 3 espaces entre les deux lettres.
echo '('*')' Noms d'entités commençant par ( et finissant par ) L'étoile n'est pas entre cotes, elle garde donc sa signification.
echo \' ' La signification de la cote a été annulée.
echo 'a b c'
a
b
c
la signification de la fin de ligne a été annulée, la commande est donc écrite sur plusieurs lignes et les retours à la ligne font partie de l'argument de la commande echo.
Tapez cette commande dans votre terminal sans faire de copier/coller pour voir ce qu'il se passe quand on tape une commande sur plusieurs lignes.


cours:échappement " «base:ajoute» «base:vide»

Comme les cotes ', les guillemets " permettent d'échapper tous les caractères encadrés, à l'exception du :

Si l'on a fait : A='" $HOME "'

Attention, si vous tapez A="'$HOME'" la variable A contiendra le contenu de la variable HOME entre cotes, car les guillemets ont annulé la signification des cotes.

2.6 : Enchaînement de commandes

cours:enchaînement «base:archive compresse» «base:échange fichiers» «base:pattern pattern»

Il est possible d'indiquer plusieurs commandes shell sur la même ligne. Il suffit de séparer chaque commande par un point-virgule ;. Elles seront exécutées les unes après les autres, même si certaines échouent.

La ligne suivante crée une archive compressée X.tar.gz contenant X/passwd et X/group :

mkdir X ; cp /etc/passwd X ; cp /etc/group X ; tar -cvf X.tar X ; rm -r X ; gzip X.tar

En tapant «curseur haut» puis «entrée» cela réexécute ces 6 commandes.


cours:enchaînement &&

Le point-virgule enchaîne des commandes les unes après les autres, même quand il y a des erreurs. «cd Trash ; rm *» va par exemple détruire tous les fichiers du répertoire courant si le répertoire Trash n'existe pas, car la commande cd fait une erreur et la suite de ligne de commande est exécutée.

Par contre, si l'on écrit «cd Trash && rm *» la commande rm ne s'exécutera que si la commande «cd Trash» a réussi et que le répertoire courant est donc Trash. && permet de tester que la commande précédente s'est bien déroulée.

2.7 : La boucle «for»

cours:boucle «for» «base:for untar» «base:for for» «base:for gzip» «base:for détruire» «base:copie verbeuse» «base:déplacer» «base:copie datée»

Le shell permet de faire des boucles afin de répéter des commandes. La boucle «for» est la plus simple et la plus souvent utilisée, l'indice de boucle est un nom de variable shell indiqué juste après le mot-clef for.

Pour chaque exemple ci-dessous, la syntaxe pour faire la boucle est indiquée de deux façons : sur une seule ligne et étalée sur plusieurs lignes. Attention, il n'y a pas de point virgule après le do :
for A in il fait beau. ; do echo "====" ; echo "$A" ; done
for A in il fait beau. do echo "====" echo "$A" done Elle affiche :
==== il ==== fait ==== beau.
for F1 in *.c *.cpp ; do cp "$F1" "$F1.bak" ; done
for F1 in *.c *.cpp do cp "$F1" "$F1.bak" done

Elle copie chaque fichier du répertoire courant dont le nom se termine par .c puis ceux dont le nom finit par .cpp sous le même nom avec .bak ajouté à la fin du nom.

Si le répertoire courant contient a.cpp et z.c cela va donc faire une copie sous les noms z.c.bak puis a.cpp.bak.

A="x y z t" ; for X in $A ; do date ; echo "$X-$X" ; sleep 1 ; done
A="x y z t" for X in $A do date echo "$X-$X" sleep 1 done Elle affiche :
Tue May 24 16:34:15 CEST 2016 x-x Tue May 24 16:34:16 CEST 2016 y-y Tue May 24 16:34:17 CEST 2016 z-z Tue May 24 16:34:18 CEST 2016 t-t

2.8 : Quelques commandes

cours:expr «theme:intro» «base:v += n» «base:expr date» «base:moyenne»

La commande expr affiche le résultat des calculs qui sont passés en argument. Cette commande est très limitée, et n'est utile que pour faire des choses très simples.

CommandeElle affiche
expr 5 "+" 38
expr 5 "*" 315
expr "(" 5 "+" 2 ")" "*" 642
expr totoZ ">" totoA1 comparaison alphabétique
expr 2 ">" 100 comparaison numérique

Ces commandes sont longues car la syntaxe de expr impose 2 choses :

Lorsque l'on a besoin de faire de nombreux calculs, on utilise un vrai langage de programmation comme Python.

3.1 : Redirections et fichiers

cours:file descriptor

Pour faire des lectures et des écritures dans des fichiers, on doit tout d'abord les ouvrir. Si l'ouverture réussit car le fichier existe et que vous avez le droit de le manipuler, alors il est ajouté à la table des descripteurs de fichier (file descriptor ou fildes en raccourci).

On référence un fichier par son indice dans la table. Par défaut, 3 fichiers sont automatiquement ouverts, leurs indices (fildes) sont :

Si d'autres fichiers sont ouverts, ils prendront les numéros 3, 4... ou réutiliseront des numéros de fichiers fermés.


cours:redirection sortie standard

Quand on veut écrire un résultat dans un fichier plutôt que sur l'écran, on redirige la sortie standard en ajoutant >CheminFichier à la commande.

Le fichier indiqué est créé s'il n'existe pas et vidé s'il existe.

La redirection s'applique seulement à la commande courante, pas aux commandes précédentes ni suivantes.
date >maintenant Le fichier maintenant contient la date courante, rien ne s'affiche sur l'écran.
cat *.c >xxx Le fichier xxx contient la concaténation de tous les fichiers du répertoire courant dont le nom se termine par .c.
echo "La date" >/tmp/xxx Le fichier /tmp/xxx contient la ligne La date, rien ne s'affiche sur l'écran.
echo "$A" ; echo "$B" >/tmp/xxx Le fichier /tmp/xxx contient le contenu de la variable B.
Le contenu de la variable A s'affiche sur l'écran.
cat ExistePas /etc/passwd >../xxx Le fichier xxx dans le père du répertoire courant contient le contenu du fichier /etc/passwd
Sur l'écran, le message d'erreur s'affiche : cat: ExistePas: No such file or directory
UneCommande >/xxx La commande n'est pas exécutée car vous n'avez pas le droit de créer un fichier dans /, sauf si vous êtes root et ce n'est pas recommandé.


cours:redirection entrée standard «base:taille fichier» «base:in out» «base:<toto >toto»

De nombreuses commandes lisent leur entrée standard quand on ne leur indique pas de nom de fichier à lire : sort, cat, uniq, wc, tail...

La commande read ne prend pas de nom de fichier en paramètre, elle lit systématiquement son entrée standard.

Pour indiquer que l'entrée standard de la commande doit être lue à partir d'un fichier on ajoute <CheminFichier à la fin commande.

sort </etc/passwd affichera les lignes du fichier /etc/passwd dans l'ordre alphabétique.


cours:redirection sortie d'erreur

Quand on veut écrire les erreurs dans un fichier plutôt que sur l'écran, on redirige la sortie d'erreur sur le fichier en ajoutant 2>CheminFichier à la commande.

Comme pour le > le fichier indiqué est créé s'il n'existe pas et vidé s'il existe et la redirection s'applique seulement à la commande courante, pas aux commandes précédentes ni suivantes.


cours:dev null

Sous Unix les périphériques raccordés à la machine sont accessibles exactement comme des fichiers. Ces fichiers de type périphérique (device) sont rangés dans /dev.

Le fichier /dev/null est particulier, tout les octets écrits dedans disparaissent, et si on le lit, on arrive directement à la fin du fichier.


cours:ajoute fin stdout

On peut rediriger la sortie standard sans effacer le contenu du fichier destination s'il contient quelque chose. Mais toujours en le créant s'il n'existe pas. Pour faire cela on utilise >> au lieu de >

echo coucou >>x ajoute la ligne 'coucou' à la fin du fichier x.


cours:ajoute fin stderr

On peut rediriger la sortie d'erreur sans effacer le contenu du fichier destination des erreurs s'il contient quelque chose. Mais toujours en le créant s'il n'existe pas. Pour faire cela on utilise 2>> au lieu de 2>

rm ExistePas 2>>x ajoute le message d'erreur à la fin du fichier x.

3.2 : Expressions régulières

cours:expression régulière

L'expression régulière (regular expression) est un outil de base en informatique qui est disponible dans tous les langages de programmation ainsi que les éditeurs de texte et de nombreux autres outils.

Le texte recherché par la commande grep est une expression régulière. Les expressions régulières fonctionnent comme les patterns, elles sont composées de caractères spéciaux qui donnent des indications sur la chaîne de caractères que l'on recherche.

Attention, d'un outil à l'autre il peut y avoir de légères variations de syntaxe.

Quand il y a plusieurs correspondances possibles en conflit, celle qui est choisie est :


cours:expreg ^

Le caractère ^ indique que la chaîne que l'on recherche est en début de ligne.

grep "^se" /etc/*.conf va afficher toutes les lignes commençant par se se trouvant dans les entités de /etc dont le nom se termine par .conf.

Attention :

Pour avoir un résultat colorié, indiquez l'option --color en premier paramètre.


cours:expreg $

Le caractère $ indique que la chaîne que l'on recherche est en fin de ligne.

grep "bash$" /etc/passwd va afficher toutes les lignes se terminant par bash qui sont dans le fichier /etc/passwd.


cours:expreg \ «base:$$»

Comme pour tous les autres caractères spéciaux du shell, on peut annuler la signification du caractère suivant en le précédent d'un backslash \. L'expression régulière \$ représente le caractère $ et non la fin de la ligne.

Rappel : les guillemets du shell n'échappent pas les backslash contrairement aux cotes.


cours:expreg .

Dans une expression régulière, le caractère . représente un caractère quelconque (comme le ? dans les patterns).


cours:expreg *

Dans une expression régulière, le caractère * multiplie l'élément qui le précède. Cela peut le multiplier zéro fois et donc le faire disparaître.

grep "xf*;" /tmp/grep/src/*.c Affiche les lignes contenant le caractère x suivi d'un certain nombre de fois le caractère f suivi du caractère ;. Cela va trouver 0xffffff; mais aussi str_idx;
grep "xff*;" /tmp/grep/src/*.c Affiche les lignes contenant xf suivi d'un certain nombre de fois le caractère f suivi du caractère ;. Cela n'affichera pas str_idx; car il doit obligatoirement y avoir un f après le x.
grep "s *= *0" /tmp/grep/src/*.c Affiche les lignes contenant s=0 avec potentiellement des espaces autour du égal.
grep "great.*value" /tmp/grep/src/*.c Affiche les lignes contenant great puis plus loin sur la même ligne value. L'expression régulière .* est une chaîne de caractères quelconques.


cours:expreg [] «base:spéciaux C»

Dans une expression régulière, les crochets [] permettent de définir une liste de caractères autorisés comme pour les patterns du shell.
Commande Affiche les lignes contenant
grep '([aeiou])' une voyelle entre parenthèses.
grep '[a-zA-Z_][a-zA-Z_0-9]*' une lettre ou _, suivi éventuellement de lettres ou _ ou des chiffres.
grep '^[^a-zA-Z]$' un seul caractère, celui ci n'étant pas une lettre. Attention la négation est ^ et non ! comme dans les patterns. Et c'est le même symbole que celui qui indique le début de ligne, c'est la position qui différencie les deux symboles.
grep '[-\]' le caractère - ou le caractère \. Le backslash n'a pas de signification entre crochets.


cours:expression régulière étendue

Les expressions régulières ne permettent pas d'exprimer tout ce que l'on veut. Les expressions régulières étendues ont donc été créées afin de pouvoir décrire bien plus de choses. Les caractères spéciaux des expressions régulières normales sont retrouvés avec le même sens dans les expressions étendues. Par contre, certains caractères normaux prennent une signification.

Les commandes possèdent souvent une option pour indiquer si l'expression régulière sera analysée comme une expression normale ou étendue.


cours:ERE +

La plupart du temps on veux répéter l'expression précédente au moins une fois. On peut donc simplifier [a-z][a-z]* en écrivant simplement l'expression régulière étendue [a-z]+. Il faut alors penser à échapper le + si l'on veut vraiment ce caractère.


cours:ERE group

Les expressions régulières étendues permettent de grouper ensemble des choses avec les parenthèses. Une fois groupées, on peut utiliser l'étoile ou le plus pour répéter le groupe.
Commande Affiche les lignes
grep -E '"(AB)+"' /tmp/grep/*/*.c contenant une répétition non vide de la chaîne AB entre guillemets, par exemple "ABABAB".
grep -E '^([a-z][0-9])+' /tmp/grep/*/*k commençant par une répétition non vide de paires lettre+chiffre, par exemple r4e3n7.


cours:ERE |

Les expressions régulières étendues permettent d'indiquer des alternatives autorisées. On sépare les alternatives avec le symbole | (pipe) qui est employé dans de très nombreux langages de programmation pour indiquer le OU booléen.

Commande Affiche les lignes
grep -E 'abcd|987' /tmp/grep/*/*.c contenant abcd ou bien 987.
grep -E '^z|:[0-9]+;|ookk' /tmp/grep/*/*.c commençant par z
ou contenant : des chiffres puis ;
ou contenant ookk.
grep -E '(is|are) (equal|different)' /tmp/grep/*/*.c contenant is equal, is different, are equal et are different.


cours:ERE ?

Les expressions régulières étendues permettent aussi d'indiquer un texte optionnel. L'expression précédente est donc répétée zéro fois (elle disparaît) ou une fois (elle est présente).
Commande Affiche les lignes
grep -E ' a( small)? buffer' /tmp/grep/*/*.c contenant a small buffer et celles contenant a buffer.
grep -E ' a (small)? buffer' /tmp/grep/*/*.c contenant a small buffer et celles contenant a buffer mais avec 2 espaces entre les 2 mots.
grep -E ' [-+]?1[0-9]*' /tmp/grep/*/*props.c contenant un espace, éventuellement le signe - ou + puis un nombre commençant par 1.

On peut se débrouiller sans ce caractère, il suffit de remplacer ab?c par a(b|)c qui fera exactement la même chose.


cours:ERE \1

Les expressions régulières étendues permettent de rechercher quelque chose qui a été trouvé dans un groupe à gauche de l'endroit où l'on est.

Pour référencer le groupe déjà trouvé, on indique \ suivi de son numéro sur un seul chiffre. \1 fait référence au premier groupe trouvé quand on lit l'expression de gauche à droite.

Commande Affiche les lignes
grep -E '(..)=\1' /tmp/grep/*/*.c Affiche les lignes contenant par exemple C2=C2, "= " ou =====. En effet le caractère . peut correspondre à un 'espace', un 'guillemet' ou un 'égal'.
grep -E '([a-z]+)=([a-z]+); \2=([a-z]+); \3=\1' Affiche les lignes contenant par exemple tmp=a; a=b; b=tmp, cette suite d'affection inverse les valeurs de a et b
grep -E '\(([a-z]+),([a-z]+)\) = \(\2,\1\)' Affiche les lignes contenant par exemple (a,b) = (b,a), qui est une autre manière d'inverser 2 valeurs. Notez bien les backslashs qui annulent la signification des parenthèses.

Attention, les guillemets n'annulent pas la signification du backslash. Il faut donc les doubler si vous voulez les utiliser.

3.3 : Quelques outils de base

cours:read «base:sauve première»

La commande builtin read lit une unique ligne sur son entrée standard (le clavier par défaut) et stocke le résultat dans les variables dont le nom est indiqué.
read MA_LIGNE La ligne complète est stockée dans la variable MA_LIGNE.
read MOT1 SUITE_DE_LA_LIGNE Le premier mot de la ligne est stocké dans la variable MOT1 et le reste est stocké dans la variable SUITE_DE_LA_LIGNE.
read A B C Le premier mot de la ligne est stocké dans la variable A, le deuxième dans la variable B et le reste est stocké dans la variable C.

La commande read n'affiche rien sur sa sortie standard.


cours:boucle while

La boucle while permet de répéter une suite de lignes de commande shell tant que la condition est réalisée.

Voici comme exemple une boucle qui écrit sur la sortie standard ce qui a été lu sur l'entrée standard. On peut écrire cette boucle sur plusieurs lignes ou bien une seule.

Sur plusieurs lignes on écrit :
while read LIGNE do echo "J'ai lu :" echo "$LIGNE" done

Sur une seule ligne (pas de point virgule après le do) : while read LIGNE ; do echo "J'ai lu :" ; echo "$LIGNE" ; done

Si vous tapez Ctrl+D qui indique une fin de fichier clavier alors la commande read va faire une erreur et donc arrêter la boucle.


cours:redirection boucle «base:déplace liste»

Si vous ajoutez une redirection sur une boucle while ou for elle porte sur toutes les commandes qui sont dans la boucle.

La redirection est faite une seule fois avant le lancement de la boucle. Chaque écriture faite par une commande complétera le fichier, et chaque lecture lira la suite du fichier.

La commande suivante écrit les noms des entités du répertoire courant dans le fichier liste : for I in * ; do echo "$I" ; done >liste

Attention, si la redirection est faite après le echo "$I" alors le fichier est vidé avant chaque écriture et contiendra seulement le dernier nom de fichier.


cours:test «base:on plonge»

La commande test permet d'évaluer une expression. Si l'expression est vraie, la commande se termine sans erreur. Dans tous les cas, aucun message n'est affiché.

Pour afficher les nombres de 0 à MAX :
I=0 while test "$I" != "$MAX" do echo "$I" I="$(expr "$I" + 1)" done

Comme la commande test est très souvent utilisée, pour que cela soit plus lisible, elle existe aussi sous le nom /usr/bin/[. On peut donc écrire [ "$I" != 10 ]

Pour afficher un triangle d'étoiles :
I="" ; while [ "$I" != "*******" ] ; do echo "$I" ; I="$I*" ; done

Il ne faut pas oublier les espaces autour des opérateurs et opérandes. Voici les opérateurs les plus courants :
-e chemin Vrai si le chemin mène à une entité qui existe.
-d chemin Vrai si le chemin mène à un répertoire.
=, != Comparaison de chaînes de caractères.
Attention "5", "+5", "5 " et " 5" sont toutes différentes.
-eq Equal. Test sur les entiers.
-ne Not Equal. Test sur les entiers.
-lt Less Than. Test sur les entiers.
-le Less or Equal. Test sur les entiers.
-gt Greater Than. Test sur les entiers.
-ge Greater or Equal. Test sur les entiers.
-a «ET» booléen entre l'expression de gauche et celle de droite.
-o «OU» booléen entre l'expression de gauche et celle de droite. Il est moins prioritaire que le «ET».
! «NON» booléen de l'expression de droite.
( et ) Pour regrouper les calculs, il ne faut pas oublier de protéger les parenthèses car elles ont une signification spéciale pour le shell.

[ ! '(' -e F1 -o "$A" = N ")" ]
est équivalent à :
[ ! -e F1 -a "$A" != N ]


cours:grep «base:$A» «base:on m'utilise ?» «base:auto référence»

La commande grep affiche sur sa sortie standard toutes les lignes qui contiennent le texte de l'on recherche.
La commande.Origine des lignes.Les lignes affichées.
grep UnTexte file1 file2 file1 et file2 contiennent le mot UnTexte.
grep -e Texte1 -e Texte2 file file contiennent le mot Texte1 ou bien Texte2.
grep -v Texte file file ne contiennent pas le mot Texte.
grep "Il fait beau" l'entrée standard (le clavier) contiennent le texte Il fait beau
Terminez la saisie avec Ctrl+D


cours:sed «theme:intro» «base:(entier)»

La commande sed (stream editor) permet de modifier un flux de donnée de taille illimitée en utilisant très peu de mémoire.

La commande sed possède beaucoup d'options et de possibilités de traitements.

Voici les exemples d'utilisation les plus courants :
Commande Résultat
sed 's/toto/titi/g' f1 f2 Lit le contenu des fichiers f1 et f2 et l'écrit sur la sortie standard en remplaçant tous les toto par titi.
sed 's/^ *//' Lit l'entrée standard et la réécrit en remplaçant les espaces en début de ligne par rien du tout. Le /g n'est pas indiqué car il est impossible de faire plusieurs fois cette substitution sur la ligne.
sed -e 's/a/A/g' -e 's/TA/ta/g' Si vous tapez La tatie. Ta tatie., cela affiche : LA tAtie. ta tAtie. La deuxième substitution a remis la lettre 'a' en minuscule.
sed -i 's/[0-9]/(&)/g' X Modifie le contenu du fichier X pour mettre entre parenthèses tous les chiffres qu'il contient.

4.1 : Processus

cours:processus

Quand un programme est lancé, le système d'exploitation crée un processus avec toutes les informations lui permettant de fonctionner :

Les processus sont identifiés par un entier unique : le PID (Process IDentifier)


cours:arbre «base:coup sur coup»

Un processus est obligatoirement créé par un processus parent, cela défini donc un arbre. La racine de l'arbre est créée au démarrage du système d'exploitation, elle porte le PID numéro 1 et s'appelle init ou systemd.

Parmis les attributs d'un process il y a le PPID (Parent PID) qui indique le processus parent, c'est initialement le processus qui lancé le programme.

Le PID 0 (père du PID 1) n'existe pas, c'est le système d'exploitation lui-même.


cours:termine

Quand un processus se termine, le système récupère toutes les ressources qu'il utilisait.

Le processus retourne une valeur lorsqu'il se termine, elle indique si le traitement qu'il a effectué s'est bien ou mal passé. C'est cette valeur qui est utilisée par la boucle while.

En langage C l'entier retourné par le programme principal (main) est la valeur de retour du processus.


cours:$$

La variable shell nommée $ contient le PID du shell qui a analysé la commande. Vous pouvez le vérifier en tapant ps ; echo $$.


cours:&

Chaque fois qu'une commande est exécutée, un processus est lancé. L'invite de commande (prompt) ne revient que quand le processus s'est terminé. Cela peut être long, si l'on veut pouvoir lancer d'autres commandes sans attendre la fin de la première, il faut lancer la commande en arrière plan (background).

Pour lancer une commande ou un pipeline en arrière plan, il suffit d'ajouter & à la fin.

Attention : sleep 5 ; echo fini & attend 5 secondes puis lance la commande 'echo' en arrière plan.

Attention : quand vous terminez le shell, les tâches en arrière plan sont détruites.

Attention : quand vous mettez un & cela termine la commande, il ne faut pas mettre de ; derrière avant de taper la commande suivante.


cours:$!

La variable shell nommée ! contient le PID du dernier processus lancé. Vous pouvez le vérifier en tapant date & echo $!.


cours:groupement «base:deuxième ligne» «base:ajoute commentaire»

On peut utiliser les parenthèses pour regrouper un ensemble de commandes dans un nouveau processus shell. Ceci permet :

La commande suivante écrit dans XXX le contenu du fichier /etc/passwd en passant la première ligne en dernier :
(read LIGNE ; cat ; echo "$LIGNE") </etc/passwd >XXX
Si après avoir exécuté cette commande vous faites echo "$LIGNE" cela n'affichera rien car la variable a disparu quand le shell exécutant le contenu des parenthèses s'est terminé.


cours:nohup

Quand vous vous déconnectez, par défaut tous les processus que vous avez lancés en arrière-plan sont tués. Si vous voulez que ces processus continuent même après votre déconnexion, il faut utiliser la commande nohup (No hang up ne pas raccrocher : ne pas couper la communication).

La syntaxe est simple : nohup votre_commande et ses paramètres &

Les sorties standard et d'erreur sont automatiquement redirigées vers le fichier nohup.out.

Attention :


cours:^Z

Vous venez de lancer une commande, mais elle prend beaucoup de temps pour s'exécuter. Vous ne voulez pas l'arrêter en faisant Ctrl+C car vous perdriez tout le travail qu'elle a déjà fait. Vous pouvez taper Ctrl+Z pour suspendre la commande, elle est alors en pause et le prompt revient. Vous pouvez alors :


cours:$?

La variable shell nommée ? contient la valeur de retour de la dernière commande exécutée. Elle contient donc 0 s'il n'y a pas eu d'erreur, sinon l'entier indique un code d'erreur dépendant de la commande.

4.2 : Commandes

cours:ps

La commande ps affiche les processus qui sont attachés à votre terminal/console. Par défaut cela affiche le PID, le TTY (TeleTYpe : nom du périphérique terminal), le temps CPU utilisé et le nom du programme.


cours:ps -e

Pour voir tous les processus lancés sur votre machine, il suffit d'ajouter l'option -e à la commande ps.


cours:ps -f

Pour avoir des informations supplémentaires sur les processus on peut ajouter l'option -f (full) à la commande ps.


cours:find «base:find paramètre» «base:find var» «base:find file»

La commande find permet de lister les chemins vers des fichiers vérifiant certaines conditions. Voici quelques exemples simples d'utilisation :

C'est une des très rares commandes à avoir des options longues précédées par un unique tiret.


cours:find ET

Si vous cherchez des fichiers devant respecter plusieurs critères, il suffit de mettre les critères les uns derrière les autres :
find . -type f -name "*.c" -mtime +7 -mtime -14
Affiche les fichiers d'extension .c modifiés il y a 2 semaines.


cours:find OU

Si vous cherchez des fichiers devant respecter l'un des critères, il suffit de séparer les critères par -o :
find . -name '*.py' -o -name "*.cpp"
Affiche les fichiers d'extension .py ou .cpp.


cours:find ET OU

Comme dans tous les langages de programmation, quand on mélange des ET et des OU, les ET sont prioritaires :
find . -name '*.py' -size +10k -o -iname '*.jpg' -size +10M
Affiche les fichiers d'extension .py de plus de 10ko et les images JPEG de plus de 10Mo.


cours:find parenthèse

Comme dans toutes les expressions algébriques, quand on ne veut pas respecter les priorités, on met des parenthèses. Mais attention, les parenthèses étant spéciales pour le shell, il faut les protéger d'une manière ou d'une autre.
find /etc '(' -name '*.d' -o -name '*.conf' \) -size +3k
Affiche les chemins des entités de /etc de plus de 3Ko dont le nom se termine par .d ou .conf.


cours:find print

La commande find quand elle ne trouve aucune action à exécuter dans ses paramètres ajoute partout l'action -print qui affiche le chemin.

Les actions sont des tests qui ont une action sur l'environnement, l'action -print est un test toujours vérifié.


cours:find exec

On peut faire exécuter à la commande find n'importe quelle commande en indiquant après les tests (les conditions) l'action -exec :
find /etc -exec echo "Chemin trouvé : {} ####" \;

On peut enchaîner des actions, ici un -exec puis un -print puis un autre -exec : find /etc -exec echo avant ';' -print -exec echo après ';'

On peut utiliser plusieurs fois {} : find /etc -exec cp {} {}.bak ';'

Avant de faire des actions dangereuses, testez d'abord en mettant echo devant la commande : -exec echo rm... au lieu de -exec rm....


cours:kill

La commande kill permet d'envoyer un signal à un processus.

Taper man 7 signal pour avoir la liste des signaux. Ceux qui vous seront le plus utiles sont :


cours:ps -H

L'option H de la commande ps permet d'afficher l'arbre des processus sous la forme d'une hiérarchie.


cours:find OU shortcut

Dans beaucoup de langage de programmation, les expressions logiques (booléenne) sont évaluées de gauche à droite. Quand on peut deviner le résultat final de l'expression, on prend un raccourci et on n'évalue pas la suite pour ne pas perdre de temps. A ET B n'évalue pas B si A est Faux et A OU B n'évalue pas B si A est Vrai.

La commande find fait de même : find . -print -o -print n'affiche qu'une seule fois le chemin car le premier 'print' retourne Vrai.


cours:true

La commande true se termine immédiatement en retournant vrai. Sa seule utilité est de faire des boucles infinies : while true ; do ... ; done


cours:set «base:les variables»

La commande builtin set permet de lister toutes les variables et fonctions définies dans le shell.

4.3 : Pipeline

cours:pipeline «base:grep grep grep» «base:ajoute date»

Le pipeline permet de mettre bout à bout des commandes en connectant la sortie standard d'une commande à l'entrée standard de la commande suivante grâce au symbole pipe |.

Les commandes sont exécutées en parallèle. Elles s'exécutent donc toutes en même temps si c'est possible.

grep y /etc/passwd | sed 's/:/===/g' | sort

Le prompt s'affiche quand toutes les commandes se sont terminées, généralement celle de droite termine en dernier car elle a besoin du résultat fourni par les commandes de gauche.


cours:priorité | et &&

Le pipeline est plus prioritaire que le &&. Le && prend la valeur de retour de la dernière commande du pipeline pour savoir si cela s'est bien passé.


cours:pipeline $?

La valeur retournée par un pipeline est celle retournée par la dernière commande qui est donc tout à droite. Cela ne dépend donc pas des valeurs de retour des autres commandes du pipeline.


cours:pipeline et ; «base:| > ;»

Le pipeline est plus prioritaire que le point-virgule ; : a | b ; c | d exécute les deux premières commandes en parallèle puis les deux suivantes.


cours:pipeline & processus

Dans un pipeline il y a autant de processus lancés qu'il y a de commandes. Quand les processus se terminent, leur état interne disparaît, notamment le répertoire courant et les variables d'environnement.

Si vous lancez A=parent ; echo enfant | read A ; echo "$A" cela affichera 'parent' car la variable A qui contient 'enfant' était dans un processus fils ('read') qui s'est terminé. La variable A contenant 'parent' n'a jamais été modifiée.


cours:filtre erreur

À droite d'une redirection > ou <, on peut indiquer un fildes au lieu d'un nom de fichier. Par exemple cat * >X 2>&1 aura sa sortie standard et sa sortie d'erreur écrite dans le fichier X.

La redirection dans le pipeline est faite avant les autres redirections. Donc, la sortie standard est l'entrée de la commande de droite.

4.4 : Script

cours:script

Un script est une suite de commandes shell que l'on enregistre dans un fichier. Il y a de très nombreuses façons de lancer un script shell, en voici quelques unes :

Avec les méthodes précédentes c'est un nouveau processus shell qui est lancé et qui exécute les commandes. Ni le répertoire courant ni les variables du shell dans lequel vous êtes ne seront modifiés.


cours:#

Les commandes tapées au clavier sont généralement à usage unique. Les scripts vont être utilisés de nombreuses fois. Ils vont aussi être relus et améliorés, il est donc nécessaire de les commenter pour aider la compréhension.

Si la ligne commence par # c'est une ligne de commentaire.

Si la ligne contient un espace suivi de # alors ce qui suit est un commentaire.

La commande suivante affiche les lignes contenant un commentaire en coloriant le commentaire :
grep --color -e '^#.*' -e ' #.*' /tmp/grep/build-aux/*.sh
Cette commande est approximative car elle trouve un commentaire dans echo " #g".


cours:$1...$9

La variable 1 contient le premier argument du script, 2 le deuxième... Si l'argument n'est pas défini, la valeur de la variable est une chaîne vide.

La variable 0 est le nom du script en train de s'exécuter.


cours:$@

La variable @ contient l'ensemble des arguments du script. Elle a un comportement unique vis-à-vis des guillemets car seul les espaces internes aux arguments sont protégés. for I in "$@" ; do echo "Argument : $I" ; done va afficher chacun des arguments sur une ligne en respectant les espaces qu'il contient.


cours:export

Les scripts shell ne récupèrent pas automatiquement toutes les variables de leur parent. Par défaut, quand vous créez une nouvelle variable elle ne sera pas connue par les scripts shell que vous lancerez.

Après avoir créé le script shell en mettant le texte echo "$A" dans le fichier affiche_A :
Vous tapez : Cela affiche :
A=5 ; sh affiche_A Une ligne vide
export A Rien, mais cela indique que l'on veut que la variable ne soit pas locale au shell. Elle sera envoyée (exportée) aux futurs shells qui seront lancés.
sh affiche_A 5
A=6 Rien.
sh affiche_A 6, pas besoin de refaire le export.

export est une commande builtin du shell.


cours:démarrage «theme:intro»

Quand vous vous identifiez ou bien ouvrez une fenêtre terminal des scripts shell sont exécutés. Ils sont exécutés sans créer un processus, ce qui veut dire que les variables définies dans le script seront connues dans le shell interactif.
/etc/profile Script exécuté à la connexion pour tous les utilisateurs.
~/.profile Script exécuté à la connexion. Ce script est normalement modifiable par l'utilisateur.
~/.bash_profile Script exécuté à la connexion si l'utilisateur utilise bash
~/.bashrc Script exécuté à chaque fois qu'un nouveau processus bash est lancé, donc à chaque fois que vous ouvrez une fenêtre si vous utilisez bash.


cours:if «base:find piper»

Comme on peut faire des petits programmes en shell il est nécessaire de tester des conditions en utilisant des if.
if cp a b; then echo OK; fi
ou bien sur plusieurs lignes :
if cp a b then echo OK fi

Affiche 'OK' si le fichier a été copié sans erreur.

Les commandes retournent 0 (vrai en shell) quand tout s'est bien passé.

if rm X;then echo 0;else echo 1;fi
ou bien sur plusieurs lignes :
if rm X then echo 0 else echo 1 fi

Affiche '0' si le fichier a été détruit sans erreur et '1' si la destruction n'a pas pu être faite.

if [ "$I" = "" ] then echo VIDE ; fi

La commande test est lancée.

Cela affiche 'VIDE' si la variable est vide.

On utilise rarement la commande if en interactif, mais il est possible de le faire.