Le(s) système(s) UNIX

Un peu d'histoire

  • 1960s: MIT, GE et Bell Labs développent un système d'exploitation pour utiliser des "mainframes" (les gros ordinateurs de l'époque): multics. Multics est intéressant mais pose de nombreux problèmes de part sa complexité.

  • 1969: Ken Thompson et Dennis Ritchie (Bell Labs) développent unics pour DEC PDP-7. L'idée est de réécrire complètement le système d'exploitation Multics en ne gardant que ce qui est simple et intéressant, et en enlevant un maximum de complexité.

  • 1970: Brian Kernnighan rejoint le projet. Unics devient Unix

  • 1972-1973: invention du langage C par Dennis Ritchie et Brian Kernnighan. Réécriture d'UNIX en C. Avant cette époque, les systèmes d'exploitation étaient écrits exclusivement en assembleur (=langage machine).

Il n'existe pas un Unix mais des Unix. Au départ, Unix appartenait à AT&T (qui possédait Bell Labs) qui vendait le système d'exploitation pour différentes machines. Les vendeurs de machines (IBM, DEC, etc.) ont modifié l'Unix original pour l'adapter à leur matériel. D'un autre côté, des Universités comme Berkeley ont également travaillé sur Unix pour améliorer la partie logiciel.

  • 1983: Richard Stallman (MIT) annonce le projet GNU ("GNU's Not Unix"): construire un système d'exploitation UNIX composé uniquement de logiciels libres. Un logiciel est dit libre (free software) si les personnes qui en reçoivent une copie ont:

    • la liberté de l'utiliser dans n'importe quel but (= commercial ou non)
    • la liberté de l'étudier et d'effectuer n'importe quelle modification
    • la liberté d'en redistribuer autant de copies qu'ils veulent s'ils en ont envie
    • la liberté d'améliorer le programme et de distribuer ces améliorations afin que tout le monde puisse en profiter On parle de mouvement open source ou libre. Richard Stallman et la Free Software Fondation ont édité une licence spécifique pour les logiciels libres: la licence GNU (GNU General Public License) qui oblige toute personne qui distribue des modifications d'un programme GNU à distribuer ces modifications sous cette même licence GNU. On parle alors de copyleft en opposition au copyright.
  • 1991: Linus Torvalds propose un noyau UNIX sous licence GNU: Linux (Linus' UNIX)

Différentes saveurs d'UNIX

Actuellement, il existe une multitude de version d'UNIX.

Des UNIX propriétaires:

  • AIX

  • HP/UX

  • MacOS X

  • ... Des UNIX libres:

  • GNU/Linux

  • OpenBSD, FreeBSD, etc.

  • GNU Hurd

  • ...

Sans compter toutes les variantes de GNU/Linux:

  • Ubuntu

  • Fedora

  • CentOS

  • Gentoo

  • Slackware

  • OpenSuse

  • ...

A cause de toutes ces variantes d'UNIX, les logiciels peuvent différer plus ou moins fortement entre versions. Cependant, leurs noms et leurs fonctionnalités principales restent identiques 😃

Caractéristiques principales

Un système Unix est composé de différents morceaux mis ensemble pour former un tout. Unix est un système complet composé:

  • d'un noyau qui gère

    • le matériel (pilotes de périphériques)
    • la mémoire
    • un système de fichiers chargé des entrées/sorties
  • de bibliothèques logiciels

  • d'un environnement de développement

  • d'une documentation associée

Unix est par essence multi-taches: à un instant donné, plusieurs tâches peuvent s'exécuter logiquement en parallèle. Il est également multi-utilisateurs: pour pouvoir travailler sur un système UNIX, un utilisateur doit s'enregistrer (connexion) et plusieurs utilisateurs peuvent travailler en même temps (session). La gestion des tâches est effectuée selon un modèle de temps partagé: chaque tâche reçoit, à tour de rôle, un petit laps de temps pendant lequel elle peut travailler.

Les entrées/sorties sont banalisées: écrire sur un fichier, sur un périphérique, sur un réseau, etc se fait toujours de la même façon. Les différences sont gérées au plus bas niveau du noyau. Cela permet une simplification maximale de l'écriture des logiciels.

Unix fournit également une interface pour l'utilisateur sous la forme d'un shell: un interprêteur de commande. Il en existe une multitude: sh, csh, tcsh, ksh, bash, ash, etc. Un programme écrit en shell est interprêté: chaque ligne du programme est analysée puis immédiatement exécutée. Un programme shell est interprêté interactivement ou en mode détaché: soit les commandes de l'utilisateur sont tapées en direct au clavier et exécuté; soit les commandes sont préalablement écrites dans un fichier qui est exécutée.

Utilisateurs

Sous Unix, il y a deux sortes d'utilisateurs:

  • l'administrateur (root) qui a tous les droits sur le système et est responsable du bon fonctionnement de celui-ci

  • les autres 😃 C'est l'administrateur qui enregistre chaque nouvel utilisateur.

Chaque utilisateur est référencé par un numéro d'identifiant unique (UID). La correspondance entre l'UID et le nom de l'utilisateur est stockée dans un fichier spécifique passwd localisé dans le répertoire /etc

Les utilisateurs sont regroupés sous formes de groupes. Les utilisateurs d'un même groupe peuvent avoir des accès particuliers sur les fichiers appartenant aux utilisateurs de ce groupe.

Chaque groupe d'utilisateurs est référencé par un numéro d'identifiant unique (GID). La correspondance entre le GID et le nom du groupe est stockée dans un fichier spécifique group localisé dans le répertoire /etc

Processus

Une tâche est appelée processus sous Unix. Un processus est une activité autonome qui exécute un programme: c'est une entité dynamique qui nait, vit en toute indépendance ou en communicant avec d'autres processus, qui peut à son tour créer d'autres processus et qui meurt.

Lorsqu'un utilisateur démarre une session Unix, le système crée un processus qui exécute un shell (par défaut). Ce processus va vivre jusqu'à la fin de la session (déconnexion). A chaque commande de l'utilisateur, ce processus (père) va créer un processus (fils) chargé d'exécuter la commande en question.

Un processus est caractérisé par un certain nombre d'informations stockées dans une table du noyau: un identifiant unique (PID), l'identifiant du processus père ayant créé ce processus (PPID), le propriétaire du processus (UID), le groupe propriétaire (GID).

Système de fichiers

Processus et fichiers

A la création d'un processus, trois fichiers sont rattachés à celui-ci: les fichiers standards. Un processus lit ses données (et ses commandes) dans le fichier standard d'entrée (standard input file); il écrit ses résultats dans le fichier standard de sortie (standard output file); et envoie ses messages d'erreurs sur le fichier standard d'erreur (standard error file).

Le processus shell qui est créé lors de la connexion d'un utilisateur est tel que le fichier d'entrée standard est connecté au clavier de l'utilisateur, et que les fichiers standards de sortie et d'erreur sont connectés à l'écran du terminal.

Tous les procesus créés par le shell original héritent de ces connexions. Ainsi, toute commande shell (exécutée dans un processus fils) lira ses données au clavier et affichera ses résultats à l'écran.

Au moment de la création d'un processus, on peut rediriger ses entrées-sorties standard. On peut ainsi connecter les fichiers standards à des fichiers par exemple.

Exemple

La commande echo affiche un message sur la sortie standard

echo Bonjour

Bonjour s'affiche à l'écran.

On peut rediriger la sortie standard dans un fichier grâce à la commande >:

echo Bonjour > f1

Bonjour est écrit dans le fichier f1.

Pour connaître le contenu du fichier f1, on peut utiliser la commande cat:

cat f1

Sous bash, la syntaxe de redirection est la suivante:

> f1 redirection de la sortie standard sur f1, avec création de f1 s'il n'existait pas, ou écrasement sinon
2> f1 idem mais pour l'erreur standard
>> f1 redirection de la sortie standard sur f1, avec création de f1 s'il n'existait pas, ou allongement de f1 sinon
2>> f1 idem mais pour l'erreur standard
< f1 redirection de l'entrée standard à partir du fichier f1
| redirection de la sortie standard d'un processus dans l'entrée standard du suivant

Définition d'un fichier

Un fichier est une suite non structurée de caractères stockée dans un fichier. Il existe deux possibilités pour lire (accéder à) un fichier: l'accès séquentiel (on lit les caractères les uns à la suite des autres) et l'accés direct (on accède au caractère de numéro donné).

Sous Unix, tout est fichier (ou presque). Un fichier peut contenir des caractères, mais aussi du binaire (code machine). Cependant, le système fait une différence sur les sortes de fichiers qu'il manipule. Il connait ainsi:

  • les fichiers ordinaires (files) qui servent à stocker des programmes ou des données

  • les répertoires (directories) qui permettent de regrouper des fichiers

  • les fichiers périphériques à accès par caractère (characters) comme un clavier

  • les fichiers périphériques à accès par block (blocks) comme un disque dur

  • les fichiers qui contiennent des références vers un autre volume et qu'on appelle liens symboliques (links)

  • les fichiers tubes (pipe) qui mettent en communication deux processus, par exemple en branchant la sortie standard d'un processus dans l'entrée standard d'un autre

  • les fichiers qui permettent d'accéder à des fichiers éloignés sur un réseau (socket)

Caractéristiques d'un fichier simple (file)

Les caractéristiques d'un fichier, autre que son contenu, sont regroupés dans un descripteur appelé i-noeuds (inode). C'est un tableau qui contient les informations suivantes:

  • le type de fichier (file, directory, link, etc.)

  • sa taille en octets

  • l'identification de son propriétaire (UID et GID)

  • les droits d'accès sur le fichier

  • trois dates: la date de création, la date de dernière modification, la date de dernier accès

  • un compteur de références

  • la liste des blocs sur le disque contenant le contenu du fichier

⚠️ le nom du fichier n'est pas contenu dans l'i-noeud.

Caractéristiques d'un répertoire

Un répertoire est un fichier particulier: c'est un tableau à deux colonnes. La première colonne contient les noms des fichiers, la deuxième contient leur numéro de i-noeud.

Ainsi pour désigner de façon externe un fichier, il faut désigner le répertoire dans lequel se trouve son nom puis ce nom. Un répertoire étant un type particulier de fichier, il suffit pour désigner un répertoire de désigner le répertoire dans lequel se trouve le nom du répertoire puis son nom, et ainsi de suite.

L'origine de la chaîne de désignation est un répertoire appelé racine (root) du système de fichiers. C'est le seul répertoire connu directement par le système. Son numéro de i-noeud a toujours pour valeur 2.

L'ensemble des répertoires et des fichiers constitue une arborescence pour laquelle les répertoires sont les branches et les fichiers les feuilles.

On parle de nom absolu d'un fichier lorsqu'on désigne le nom d'un fichier par son chemin depuis la racine. Par exemple: /home/toto/f1 désigne le fichier f1 contenu dans le répertoire toto lui-même contenu dans le répertoire home contenu dans le répertoire racine / (la racine root est désigné par /).

Tout répertoire contient par défaut deux entrées particulières: . et ..

  • . désigne le répertoire lui-même (ou répertoire courant)

  • .. désigne le répertoire père

Exemple

/:

 | i-noeud du répertoire | nom | i-noeud | 
 | ---------------------- | --- | ------- | 
 | 2                      | ..  | 0       | 
 |                        | .   | 2       | 
 |                        | 35  | usr     | 
 |                        | 40  | etc     | 

usr:

 | i-noeud du répertoire | nom   | i-noeud | 
 | ---------------------- | ---   | ------- | 
 | 35                     | ..    | 2       | 
 |                        | .     | 35      | 
 |                        | bin   | 54      | 
 |                        | local | 55      | 

etc:

 | i-noeud du répertoire | nom    | i-noeud | 
 | ---------------------- | ---    | ------- | 
 | 40                     | ..     | 2       | 
 |                        | .      | 40      | 
 |                        | passwd | 41      | 

bin:

 | i-noeud du répertoire | nom  | i-noeud | 
 | ---------------------- | ---  | ------- | 
 | 54                     | ..   | 35      | 
 |                        | .    | 54      | 
 |                        | echo | 75      | 
 |                        | cat  | 189     | 

Ainsi, la commande cat a un chemin absolu /usr/bin/cat.

Lors de l'utilisation de l'interprêteur de commandes (shell), on peut soit désigner un fichier par son chemin absolu, soit par un chemin relatif à partir du répertoire courant. A chaque instant, l'utilisateur émet ses commandes à partir d'un répertoire courant (le répertoire par défaut est appelé répertoire maison ou home directory). Tout fichier peut être désigné relativement à se répertoire courant.

Par exemple, si on est situé dans le répertoire /home/toto, le fichier /usr/bin/cat peut être désigné également par ../../usr/bin/cat.

Système de fichiers et volumes

Dans un système de fichiers Unix, il n'existe qu'une seule racine root. Or, la composition du système de fichiers peut provenir d'un disque local, de plusieurs disques locaux, voire du réseau (partage de fichiers).

Sous Unix, pour conserver une arborescence unique, chaque arborescence (ou partie) autre que le système de fichiers principal est monté (mount) sur l'arborescence principale.

Sous Linux, la table contenant l'ensemble des volumes (arborescence) mountés sur l'arborescence principale est obtenue grâce à la commande mount.

mount

La commande df permet de connaitre également l'ensemble des volumes montés mais aussi leur occupation.

df

Forme générale des commandes

Dans un shell (bash ici), il existe une multitude de commandes accessibles par l'interprêteur de commandes. Cependant, ces commandes respectent toutes , ou presque, la même syntaxe:

commande [option] [argument]
  • commande est le nom de la commande que l'on veut exécuter

  • Les [...] dans [option] et [argument] signifie que les options et les arguments sont facultatifs. Ainsi la commande peut être appelée seule et s'exécutera avec ses options par défaut.

  • Les différents composants de la commande sont séparées par des espaces.

  • [option] correspond aux options. Elles sont généralement de la forme -o (avec un tiret) ou --option (version longue avec deux tirets). Les options peuvent parfois être suivies d'arguments propres aux options (par exemple -o toto ou --option=toto). Si plusieurs options sont définies, on peut souvent les abréger (par exemple -a -b devient -ab).

  • [argument] correspond aux arguments propres de la commande.

Exemple:

ls
ls repertoire
ls -d repertoire
ls -l -a
ls -la
ls -la repertoire

Documentation

Sous Unix, différentes documentations sont accessibles afin de connaître la façon d'appeler une commande, ses options et ses arguments possibles.

man: les pages manuels

La commande man permet d'accéder sur le terminal à la documentation d'une commande. man est suivi du nom de la commande pour laquelle on veut une documentation.

man ls
man man
  • man -k permet de rechercher un mot-clé dans les pages man.

info: la documentation hyper-texte

La commande info permet d'accéder à une documentation souvent plus complète que man. Par contraste à man qui décrit une commande en une seule page (qui peut être très longue), info utilise l'hyper-texte afin d'autoriser une navigation dans la documentation.

Un récapitulatif des commandes sous info est obtenu en tapant ? lors de l'exécution d'info.

info info
info ls

/usr/share/doc: la documentation logicielle officielle

Lorsqu'un logiciel est installé à partir de son code source, on place généralement toute la documentation dans /usr/share/doc. Cette documentation peut-être très variée (.txt, .ps, .pdf, etc.) et ne concerne pas forcèment seulement l'utilisation de la commande.

Howto sur http://www.tldp.org

Outre les différents forums existant sur le Net et les recherches Google, il existe un site très intéressant qui regroupe des documentations sur la mise en place de logiciels ou de série de logiciels. The Linux Documentation Projet regroupe des contributions variées allant de l'utilisation d'une souris à la mise en place de réseaux complexes (firewall, haute performance, etc.). Ces documentations sont éditées sous une license GNU.