FIP SIT151 - Introduction à Unix/Linux

Christophe Lohr

Automne 2023

Grace Hopper - 1960 Dennis Ritchie & Ken Thompson - 1972

1 Introduction

1.1 Le système d’exploitation

Le système d’exploitation peut être vu comme une application particulière, chargée en mémoire centrale, très rapidement après la mise sous tension de la machine (juste après que que programme résidant en mémoire EEPROM se soit exécuté, ce qu’on appelle le BIOS dans l’architecture PC). Cette application permet d’utiliser l’ordinateur, elle gère les applications qui s’y déroulent et sert d’interface entre elles et les périphériques matériels. La mémoire centrale est chargée avec le Système d’exploitation d’une part et avec les programmes applicatifs lancés par les utilisateurs d’autre part. Le système d’exploitation contient des modules spécifiques aux périphériques qu’il sait contrôler, ce sont les pilotes (drivers en anglais)

1.2 Historique

Pointeurs:

1.3 De Unix à Linux

Sur clef USB:

2 Le système de fichiers

2.1 Structure, nommage, droits

Il existe quelques autres types de fichiers pouvant apparaître dans l’arborescence:

Les liens peuvent être de deux types: liens durs (version originale des liens sur Unix) et les liens symboliques (type l), version apportée par l’Unix de Berkeley (BSD) pour augmenter la portée des liens natifs (durs). Les liens durs ne peuvent être réalisés qu’entre références (nom dans un répertoire, on dit aussi entrée dans un répertoire) sur un même système de gestion de fichiers. Les liens symboliques peuvent passer les frontières physiques des système de fichiers.

Une organisation standardisée sous Unix: Filesystem Hierarchy Standard (http://www.pathname.com/fhs/).

Pour visualiser la liste des fichiers cachés il faut utiliser l’option -a de ls. Pour les outils graphiques de gestion de fichiers (les «explorateurs» dirions nous sous un autre système d’exploitation bien connu), il existe une option de paramétrage dans les menus de configuration (parfois appelés «préférences»).

Un lien est un nom de fichier, une référence dans un répertoire. Un fichier peut être référencé plusieurs fois, on dit alors qu’il a plusieurs liens. Ces liens peuvent être symboliques ou physiques (on dit alors «lien dur»). Un lien dur est tout simplement une référence dans un répertoire sur un fichier déjà référencé. Les deux références sont associées au même inode. Dans le schéma ci-dessus on pourrait par exemple créer un lien sur fichierB dans un répertoire quelconque. fichierB serait alors accessible par deux chemins. Les deux noms auraient le même inode.

La commande ln permet de créer des liens durs ou symboliques.

Les liens symboliques sont des fichiers presque normaux, seul leur type est spécifique. Leur contenu est le chemin d’accès au fichier réel.

Les liens durs ne peuvent être effectués qu’à l’intérieur d’un même système de fichiers (point commun: l’inode). Les liens symboliques peuvent sans problème franchir les frontières physiques des systèmes de fichiers.

Conceptuellement, un lien peut être considéré comme un raccourci sous Windows (si vous connaissez W...)

Il arrive à beaucoup de gens d’écrire un petit fichier d’essai et de le nommer test. Après qu’il soit rendu exécutable, il est essayé... Et...Surprise ! le résultat n’est pas du tout celui attendu... Car la commande lancée, de nom test, n’est pas celle qu’on croit, il s’agit de /bin/test et non le test du répertoire courant (si la variable d’environnement PATH ne contient pas le caractère «.» dans sa liste avant /bin).

Il suffit pour remédier à cela d’entrer alors la ligne de commande ./test et le tour est joué.

En général, par défaut, le «.» ne figure pas dans la variable PATH pour des raisons de sécurité élémentaire et toute commande se situant dans le répertoire de travail (celui dans lequel on se trouve) doit se lancer avec la séquence ./nomFichier (à moins que le répertoire de travail ne soit listé naturellement dans la variable PATH).

Si les droits en écriture/lecture/exécution sont assez évidents à comprendre il n’en va pas de même pour les trois premiers: S_UID, S_GID et le Sticky bit:

Remarque importante: le sticky bit est maintenant utilisé sur des répertoires ouverts en lecture/écriture à tous pour restreindre le droit d’effacement des fichiers qui s’y trouvent au seul propriétaire de ces fichiers. Cas des répertoires /tmp, /var/tmp, /usr/tmp. Voir aussi la notion d’attribut avec la commande chattr.

Si un répertoire est interdit de passage (i.e. le droit x est ôté), on ne peut pas s’y déplacer, on ne peut pas non plus descendre dans ses sous-répertoires, même si ceux-ci sont autorisés. Un droit x ôté est comme un obstacle infranchissable.

Si un répertoire à le droit w pour les utilisateurs non propriétaires, n’importe qui peut y créer un fichier, mais n’importe qui peut aussi supprimer ce fichier. Ce serait le cas pour les répertoires contenant les fichiers temporaires (/tmp, /var/tmp) si ceux-ci n’étaient pas munis du droit t.

Chacun chez soi... Et chacun maître chez soi. Si un utilisateur veut ouvrir son répertoire à tout le monde il en a le droit. Il a aussi le droit de fermer son répertoire à tous (même à lui même, ce qui est embêtant pour lui sur le moment, mais il peut modifier à nouveau les droits pour se ré-autoriser...).

Les répertoires ouverts en lecture sont visitables pour autant qu’ils aient le droit x positionné. Les répertoires /tmp, /var/tmp, /usr/tmp sont ouverts à tous et tous peuvent y créer des fichiers et les supprimer. Généralement ces répertoires sont munis du sticky bit afin de restreindre le droit d’effacement aux seuls propriétaires des fichiers.

Il est donc possible de «se promener» dans la plus grande partie du système de fichiers. Seuls certains répertoires et fichiers sensibles sont interdits.

Ces fichiers sont créés par la commande mknod, ils peuvent être créés n’importe où mais en général on les trouve dans /dev.

Cette manière de voir les périphériques permet de considérer ceux-ci comme des fichiers (certes spéciaux, mais fichiers quand même), ainsi les échanges entre les applications et les périphériques se font essentiellement par des écritures et des lectures, comme pour des fichiers normaux.

2.2 Organisation sur disques

bootstrap: en français «amorçage», démarrer, c’est la suite rigoureuse d’opérations élémentaires que doit réaliser l’ordinateur pour démarrer alors qu’il n’a pas encore démarré. (Le terme semble provenir d’une plaisanterie anglaise populaire: tirer sur les languettes de ses bottes pour s’envoler.)

zone de swap: en français «zone d’échange», permet de «décharger» la mémoire centrale si celle-ci est saturée. Les processus endormis (en attente d’un événement quelconque) sont transférés dans cette zone. Sa taille peut influencer le fonctionnement d’applications «gourmandes» en mémoire. Il est recommandé qu’elle soit au moins égale à la taille de la mémoire centrale. Elle peut être augmentée temporairement par des fichiers particuliers s’il reste suffisamment d’espace sur un une partition d’un disque munie d’un système de fichiers Linux. Cette possibilité est cependant à éviter car le swap sur un fichier du système de fichiers est moins efficace (moins rapide) que le swap direct sur une partition de disque dédiée. La commande swapon permet de rendre accessible la zone de swap pour le système. Cette même commande permet de rajouter des fichiers de swap si nécessaires (crées par la commande swapon). on peut avoir plusieurs systèmes de fichiers de natures différentes: FAT, NT ou linux (ext2, ext3, etc...). Attention danger pour l’intégrité des partitions NT si autorisation en écriture.

Le super bloc contient la structure du système de fichiers: structure à l’origine et structure courante (nombre de blocs, nombre d’inodes, nombre de blocs libres...).

Le super bloc est copié en mémoire centrale à l’initialisation de la machine et sauvegardé sur disque régulièrement via le thread noyau pdflush (avant linux 2.6 on avait le démon bdflush aidant le thread noyau kupdated). Ceci pose un problème au cas ou la machine s’arrête inopinément avant que le super bloc n’ait été recopié sur le disque dur. Le système de fichier apparaît alors corrompu au reboot. L’utilitaire fsck est lancé alors automatiquement pour réparer ce qui est possible. Si on a besoin d’arrêter le système en urgence (arrêt par coupure du courant par exemple) il est recommandé d’utiliser avant la commande sync pour faire ce travail de recopie des super blocs sur disque. Au prochain redémarrage il ne devrait alors pas y avoir de problème. La taille de la table des inodes n’est pas variable, elle est calculée à la création du système de fichiers en fonction de la taille de la partition. Voir la commande dump2fs et ses résultats.

Un système de gestion de fichiers journalisé tel que ext3fs permet de "mieux" se récupérer après un arrêt brutal: au redémarrage les transactions avortées sont rejouées.

Le système de fichier global peut être constitué de plusieurs systèmes de fichiers de natures identiques ou différentes.

Dans le schéma ci-dessus on a choisi de créer 3 partitions formatées en système de fichier Linux (ext2 ou ext3):

Les systèmes de fichiers sont raccrochés à la racine lors du lancement du système. D’abord le système crée la racine virtuelle qu’il nomme «/». Il raccroche dessus immédiatement le système de fichiers racine, puis ensuite il raccrochera les autres systèmes de fichiers selon l’ordre indiqué dans le fichier /etc/fstab.

L’utilitaire permettant de raccrocher un système de fichiers à l’arborescence globale est la commande mount.

La question pertinente est de savoir combien de partitions il faut pour installer le système. On peut laisser la procédure d’installation faire seule mais les choix automatiques ne sont pas toujours satisfaisants.

Notons que lorsqu’un utilisateur insère un CD ou une clé USB, le volume apparaît alors comme par magie sur son bureau. Techniquement, c’est bien mount qui est utilisé (de façon cachée) par le gestionnaire de fichier.

3 Utilisation courante

3.1 Les commandes et leur syntaxe

La variable PATH peut aussi être configurée dans $HOME/.bash_profile mais ce fichier n’est pas lu systématiquement quand on ouvre une fenêtre terminale. Il n’est lu que lors de la connexion (le login) dans une console virtuelle (que l’on accède à partir de l’interface graphique avec le jeu de touches clavier <Ctrl-Alt-F1>.

Si on modifie la variable PATH directement dans le Shell par la commande export ci-dessus, la modification est prise en compte dans le shell, évidemment, mais dans CE shell seulement... Pas dans le shell de la fenêtre terminal d’à côté par exemple, et c’est très déconcertant pour le néophyte. Pour comprendre pourquoi une telle modification n’est pas vue immédiatement de tous les shells il faut savoir qu’un shell en cours d’exécution est avant tout un processus qui hérite des propriétés du processus «terminal» lui-même (le processus qui «dessine» la fenêtre à l’écran). Ces processus forment une arborescence et héritent leurs propriétés les uns des autres d’une manière descendante. Le processus «terminal» lance le processus Shell. Le processus Shell hérite de son «père», le terminal. Si on modifie les propriétés d’un processus, les modifications pourront être vue par des sous-processus mais pas par les processus au dessus dans l’arborescence. Ni à fortiori par ceux «à coté», ou dans une autre arborescence...

Pour qu’une modification d’environnement soit permanente il suffit qu’elle soit écrite dans un fichier de configuration pris en compte systématiquement lors du lancement du Shell. Le fichier personnel .bashrc est le plus approprié pour le shell bash ; et le fichier .tcshrc (ou .tcsh.PERSO) pour le shell tcsh.

C’est en fait la philosophie de base de l’utilisation d’Unix: une pléiade de petits utilitaires que l’on assemble au moyen de tubes pour réaliser une grande tâche. Le contraire des approches monolithiques.

Note: lors de l’exécution de commande1 | commande2, les deux programmes sont exécutés en parallèle. Sur d’autres systèmes mono-tâche comme MS-DOS, il y a d’abord l’exécution du premier programme en sauvegardant sa sortie dans un fichier temporaire, puis ensuite l’exécution du second programme en lisant le fichier temporaire...

Ce ne sont quelques commandes classiques que tout utilisateur d’Unix finit par connaître par coeur au bout de quelque temps de pratique...

Même si il est évidemment difficile de les connaître toutes dans le détail, il est bon de savoir qu’elles existent et de savoir retrouver leur documentation en temps utile.

Ces commandes sont rangées typiquement dans /bin et /usr/bin

http://en.wikipedia.org/wiki/List_of_Unix_programs

3.2 La documentation

Les pages du «manuel» Unix, en ligne (Sun fournissait un gros classeur du man imprimé...).

La source d’information de référence incontournable. Ne pas poser une question dans les forums de discussion dont la réponse est dans le man... sous peine d’être bien mal accueilli:-)

Attention: les pages du man ne sont pas des cours ni des tutoriels, mais du condensé d’information. Chaque mot est important. Il est parfois difficile de se plonger dedans, mais les pages de man sont toutes rédigées selon la même manière, tant est si bien que lorsque l’on a pris le plis, il est relativement facile de s’y retrouver rapidement.
Le man est organisé en sections:

  1. Commandes utilisateur
  2. Appels système
  3. Fonctions de bibliothèque
  4. Fichiers spéciaux
  5. Formats de fichier
  6. Jeux
  7. Divers
  8. Administration système
  9. Interface du noyau Linux

Chaque section possède une page d’introduction qui présente la section, disponible en tapant man <num_section> intro.

Note: les commandes internes au shell (p.ex. cd pwd history etc.) n’ont pas de page de man car ce ne sont pas des programmes, mais juste des mots clefs reconnus et interprétés directement par le shell. Ces commandes sont donc expliquées dans la documentation du shell lui-même. Par exemple, si vous cherchez de la documentation sur la commande cd et que vous avez bash comme shell, regardez dans le man bash. Une autre façon de faire est de taper help cd (En effet, help est une autre commande interne de bash qui affiche de la documentation sur les commandes internes de bash.)

4 Les processus

4.1 Environnement, cycle de vie

Le fils est un clone du père mais il y a une mutation génétique... Le père demande la création du fils via une fonction de bas niveau (un appel système). Cette fonction rend 0 dans le processus fils et une valeur strictement positive dans le processus père. Cette valeur dans le père est en fait le numéro de processus du fils. Le programmeur profite de cette différence pour différentier le code exécuté par les deux processus. Sinon les deux exécuteraient strictement la même chose.

Pendant l’exécution d’un fichier ayant le bit S_UID positionné on a les droits du propriétaire du fichier, les droits d’un autre utilisateur, sans lui demander... Mais si le fichier exécuté possède ce droit c’est que son propriétaire l’y a mis, car lui seul peut le faire, ou l’administrateur, ou une application malicieuse...

Tout utilisateur peut avoir chez lui de tels fichiers pour des raisons qui lui sont propres et pour que des applications qui lui sont personnelles puissent fonctionner pour tout le monde. L’administrateur peut toutefois demander aux utilisateurs de justifier la présence de tels fichiers, c’est son droit et peut être même son devoir.

De tels fichiers existent et appartiennent à root, l’administrateur. S’ils sont vulnérables à des attaques de type débordement de tampon (buffer overflow) alors la sécurité du système entier est gravement compromise.

Sur certains systèmes les paramétrages des terminaux ou des émulateurs de terminaux sont tels que les associations de touches <Ctrl-Z> ou <Ctrl-C> ne fonctionnent pas. On peut le vérifier avec la commande stty -a qui affiche le paramétrage du terminal.

Exemple:

[bash]$ stty -a
speed 38400 baud; rows 25; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
...

Remarquer le paramètre intr = ^C, l’accent circonflexe indique la touche <Ctrl>. En fait, intr est le paramètre permettant de tuer rapidement un processus. Voir aussi susp. Et faire man stty.

On peut changer le paramétrage intr avec: [bash]$ stty intr ^F

Les raccourcis claviers (p.ex. <CTRL-C>) pour envoyer les signaux au processus en cours dans le shell sont paramétrés au niveau du terminal: stty -a.

En Shell (sh, bash, ksh) on peut récupérer le code de retour du exit du fils dans la variable $?.

Si la commande correspond à un fichier exécutable, alors un processus fils est créé pour l’exécution. Le Shell ne reste en attente que si la ligne de commande entrée au terminal ne se termine pas par un caractère «&», auquel cas le shell revient sans attendre et renvoie l’invite à l’écran. Dans ce dernier cas, il est néanmoins capable de gérer proprement la terminaison de son fils afin que ce dernier ne reste pas zombie.

5 L’interface graphique X-Window

Le principe d’une interface graphique émerge à partir des années 80, du fait de l’évolution du matériel, avec différents concepts et architectures logicielles (client-serveur, fenêtres, multi-application, etc.). (Voir https://en.wikipedia.org/wiki/History_of_the_graphical_user_interface)

Dans le monde Unix, Sun développa NeWS, un système graphique client-serveur basé sur un interpréteur PostScript (l’ancêtre du format PDF), et avec une couche d’adaptation X-Window. Techniquement intéressant, mais les conditions de licences de Sun a incité les développeurs de l’époque à se tourner vers la solution libre X-Window.

Le projet Wayland, débuté vers 2010, ambitionne de remplacer X-Window, en offrant des facilités pour gérer la composition (c.à.d. gérer la transparence entre fenêtres qui se superposent ou des effets d’ombrage), et le rendu direct, en exploitant plus simplement les capacité matérielles des cartes graphiques modernes, mais en abandonnant en grande partie le fonctionnement en réseau. Une couche de compatibilité X-Window est proposée. Son adoption dans les distributions Linux classiques a débutée mais reste encore prudente, le système X-Window restant la référence.

5.1 Client-serveur, authentification, bureau

Une documentation (particulièrement pédagogique et ludique) sur le fonctionnement interne de X-Windows: https://magcius.github.io/xplain/article/

6 Les scripts shell

6.1 Historique, fonctionnement, programmation

Deux familles qui se distinguent essentiellement par leur syntaxe de programmation.

Ensuite, d’autres variantes apportent leur lot de fonctionnalités pour le confort de l’utilisateur, ou des extensions du langage et de la syntaxe de programmation.

Ne manquez pas de lire "Top Ten reasons not to use the C shell" (http://www.grymoire.com/Unix/CshTop10.txt). Gardez tout de même un œuil critique. Notez que si le shell par défaut qui vous est proposé ne vous convient pas vous pouvez en changer par la commande chsh (ou ypchsh si votre compte utilisateur est géré par NIS). Lire le man avant, et pensez qu’il y aura peut être quelques effets de bord avec des scripts de configuration.

Pour apprendre à faire des scripts shell:


Ce document a été traduit de LATEX par HEVEA