Quelques systèmes:
Qu'est-ce qu'un système d'exploitation ?
Quelles sont les ressources d'une machine?
Haut niveau | Applications: navigateur Web, éditeur de texte, anti-virus, jeu, compilateur, … |
↓ | Système d'exploitation:
|
Bas niveau | Matériel: CPU, mémoire, périphériques, … |
1965 | MultICS: Multiplexed Information and Computing Service (Bell & MIT) |
1969 | Unix: 1ère version en assembleur (AT&T) |
1972-73 | Unix réécrit en C |
1976 | Invention de TCP/IP |
1977 | Berkeley Software Distribution (BSD) |
1985 | Unix System V |
1988 | Minix |
1992 | Linux |
Applications | |
Interface utilisateur | Services |
Noyau (kernel) | |
Micro-code | |
Matériel |
Applications | |
Bibliothèques (libc, DirectX, OpenGL, …) |
Appels systèmes |
Noyau
pilotes de périphériques
ordonnanceur (gestion du temps CPU)
gestionnaire de mémoire système de fichier |
Matériel |
Exemple de session shell:
$ ls
Documents Downloads Public Person
$ cd Documents
$ ls
compte_rendu.txt
$ mv compte_rendu.txt cr.txt
$ ls
cr.txt
Un fichier est une collection d'informations numériques réunies sous un même nom et enregistrée sur un support de stockage
Ne pas confondre:
Nom | |
Propriétaire | utilisateur qui possède ce fichier |
Groupe | groupe d'utilisateurs qui possède ce fichier |
Emplacement | localisation du fichier sur le support physique |
Taille | en octet (peut être la taille réelle ou la taille occupée sur le support) |
Permissions | « qui a quel droit » sur le fichier (lecture, écriture, exécution, …) |
Type | |
Dates | dernier accès, dernière modification, création, … |
Usuellement, les fichiers sont regroupés en répertoires. Les répertoires sont imbriqués les uns dans les autres de manière a former une arborescence.
Sous Unix il y a un répertoire racine, « / »
(slash) qui contient toute l'arborescence du système.
Chaque utilisateur possède aussi un répertoire personnel
Un chemin est une liste de répertoire à traverser pour
atteindre un fichier ou répertoire donné.
Sous Unix, le séparateur de chemin est le « / »
Les chemins absolus commencent par un / et
dénotent des fichiers à partir de la racine. Exemple:
/home/kim/Documents/ProgInternet/cours01.pdf
Les chemins relatifs dénotent des fichiers à partir du
répertoire courant. Exemple:
Documents/ProgInternet/cours01.pdf
si on se trouve dans le répertoire /home/kim
Les noms spéciaux: « . » dénote le répertoire
courant,
« .. » le répertoire parent, « ~ » le répertoire de
l'utilisateur et « ~toto » le répertoire de l'utilisateur
toto
Le shell affiche un invite de commande
(prompt). Exemple:
kim@machine $
On peut alors saisir une commande:
kim@machine $ ls *.txt
Le shell affiche la sortie de la commande:
fichier1.txt fichier2.txt
Certains caractères doivent être précédés d'un « \ » (échappés):
kim@machine $ ls mon\ fichier\#1.txt
Une ligne de commande a la forme:
prog item1 item2 item3 item4 …
Certains caractères sont interprétés de manière spéciale par le shell. Ces caractères sont « expansés » selon des règles. Si la forme expansée correspond a un ou plusieurs fichiers existants, alors leurs noms sont placés sur la ligne de commande. Sinon la chaîne de caractère de départ garde sa valeur textuelle.
Règles d'expansion:
* n'importe quelle chaîne
? n'importe quel caractère
[ab12…] un caractère dans la liste
[^ab12…] un caractère absent de liste
[a-z] un caractère dans l'intervalle
[^a-z] un caractère absent de l'intervalle
?(m1|…|mn)
@(m1|…|mn)
*(m1|…|mn)
+(m1|…|mn)
k motifs parmi mi
?: 0 ≤ k ≤ 1
@: k = 1
*: k ≥ 0
+: k ≥ 1
!(m1|…|mn):
ni m1, …, ni mn
ls !(*[aeiouy]?)
La chaîne « !(*[aeiouy]?) » est remplacée par la liste de tous
les fichiers dont l'avant dernière lettre du nom n'est pas une
voyelle. S'il n'y a pas de tel fichier, la chaîne
« !(*[aeiouy]?) » est passée à la commande ls.
ls [0-9]* affiche la liste des fichiers commençant par un
chiffre
ls +(abc) affiche la liste des fichiers dont le nom est une
répétition de « abc ».
Sous Unix un utilisateur est identifié par son login (ou nom
d'utilisateur). Chaque utilisateur est dans un groupe
principal.
Chaque fichier appartient à un utilisateur et à un groupe.
Chaque fichier possède 3 permissions pour son propriétaire, son groupe
et tous les autres. Les permissions sont lecture, écriture, exécution
(plus d'autres non abordées dans ce cours).
Permission | fichier | répertoire |
---|---|---|
lecture (r) | lire le contenu du fichier | lister le contenu du répertoire |
écriture (w) | écrire dans le fichier | supprimer/renommer/créer des fichiers dans le répertoire |
exécution (x) | exécuter le fichier
(si c'est un programme) |
rentrer dans le répertoire |
$ ls -l
drwxr-x--- 9 kim prof 4096 Sep 7 21:31 Documents
chmod permissions chemin1 … cheminn
modifie les permissions des fichiers 1 à n. La chaîne
permissions est soit une suite de modifications de
permissions symbolique soit l'ensemble des permissions données
de manière numérique:
chmod 755 fichier.txt
chmod u-w,a+x,g=w fichier.txt
On groupe les bits de permissions par trois puis on convertit en décimal:
Utilisateur | Groupe | Autres | ||||||
---|---|---|---|---|---|---|---|---|
r | w | x | r | w | x | r | w | x |
1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
6 | 4 | 0 |
Le fichier est lisible et modifiable mais pas exécutable par son
propriétaire, lisible pour le groupe. Les autres ne peuvent ni le lire
ni le modifier.
cible modifieur permission
Exemple:
chmod u+rw,u-x,g+r,g-wx,o-rwx fichier.txt
Pour des raisons d'organisation, on veut pouvoir « voir » le même fichier ou répertoire sous deux noms différents (ou à deux endroits différents). Par exemple:
$ ls -l Documents/Cours
total 8
drwxr-xr-x 3 kim prof 4096 Sep 9 11:30 Licence
drwxr-xr-x 3 kim prof 4096 Sep 9 11:30 Master
$ cd Documents/Cours/Master; ls
Compilation XMLProgInternet
$ cd XML_Prog_Internet; ls
cours01 cours02 cours03 cours04 cours05 cours06 Prereq
$ ls -l Prereq
lrwxrwxrwx 1 kim prof 28 Sep 9 11:30 Prereq -> ../../Licence/UnixProgWeb/
La commande ln permet de créer des liens symboliques. Un lien est un petit fichier qui contient un chemin vers un fichier de destination.
Exemple d'utilisation
$ ln -s ../foo/bar/baz/toto.txt rep/titi.txt
crée un lien vers le fichier toto.txt sous le nom titi.txt (chacun placé dans des sous/sur répertoires)
Cela permet de créer l'illusion que la cible a été copiée à l'identique, sans les inconvénients
La commande rm fichier efface un fichier définitivement
La commande rm -d rep efface un répertoire s'il est vide
La commande rm -r rep efface un répertoire récursivement
mais demande confirmation avant d'effacer des éléments
La commande rm -rf rep efface un répertoire
récursivement et sans confirmation
Toute suppression est définitive
Gag classique :
$ mkdir \~
...
$ ls
Documents Photos Musique ~
$ rm -rf ~
☠ ☠ ☠ ☠ ☠ ☠
La commande man permet d'obtenir de l'aide sur une commande. Lors qu'une page d'aide est affichée, on peut la faire défiler avec les touches du clavier, la quitter avec « q » et rechercher un mot avec la touche « / »
LS(1L) Manuel de l'utilisateur Linux LS(1L)
NOM
ls, dir, vdir - Afficher le contenu d'un répertoire.
SYNOPSIS
ls [options] [fichier...]
Options POSIX : [-1acdilqrtuCFR]
Options GNU (forme courte) : [-1abcdfgiklmnopqrstuxABCD
FGLNQRSUX] [-w cols] [-T cols] [-I motif] [--full-time]
[--format={long,verbose,commas,across,vertical,single-col
umn}] [--sort={none,time,size,extension}]
[--time={atime,access,use,ctime,status}]
[--color[={none,auto,always}]] [--help] [--version] [--]
DESCRIPTION
La commande ls affiche tout d'abord l'ensemble de ses
arguments fichiers autres que des répertoires. Puis ls
affiche l'ensemble des fichiers contenus dans chaque
répertoire indiqué. dir et vdir sont des versions de ls
affichant par défaut leurs résultats avec d'autres for
mats.
La commande find rep critères permet de trouver tous les fichiers se trouvant dans le répertoire rep (ou un sous répertoire) et répondant à certains critères. Exemples de critères :
Comment trouver toutes les options de la commande find ? man find
Trouver tous les fichiers (dans un sous-répertoire) du répertoire courant dont le nom se finit par .jpg et dont la taille est supérieure à 1 Mo
find . -name '*.jpg' -a -size +1M
Trouver tous les fichiers (dans un sous-répertoire) du répertoire courant dont le nom se finit par .mpg (sans tenir compte de la casse) et dont la taille est supérieure à 10 Mo, et rajouter l'extension .bak à ces fichiers
find . -iname '*.mpg' -a -size +10M -exec mv {} {}.bak \;
On verra comment composer ces commandes pour exécuter des opérations complexes
Dans le shell, l'opérateur | permet
d'enchaîner la sortie d'un programme avec l'entrée d'un
autre:
$ ls -l *.txt | sort -n -r -k 5 | head -n 1
-rw-rw-r 1 kim kim 471 Sep 14 16:25 bd.txt
-rw-rw-r 1 kim kim 234 Sep 15 17:46 foo.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
-rw-rw-r 1 kim kim 471 Sep 14 16:25 bd.txt
-rw-rw-r 1 kim kim 234 Sep 15 17:46 foo.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
Quelques exemples de commandes problématiques :
$ sort fichier.txt > fichier.txt
fichier.txt devient vide ! Il est ouvert en écriture et tronqué avant l'exécution de la commande.
$ sort < fichier.txt > fichier.txt
fichier.txt devient vide ! Il est ouvert en écriture et tronqué avant l'exécution de la commande.
$ sort < fichier.txt >> fichier.txt
fichier.txt contient son contenu original, suivi de son contenu trié !
$ cat < fichier.txt >> fichier.txt
fichier.txt est rempli jusqu'à saturation de l'espace disque !
La commande sort doit trier son entrée standard. Elle doit donc la lire intégralement avant de produire la moindre sortie. Pour
$ sort < fichier.txt >> fichier.txt
on a donc :
La commande cat ré-affiche son entrée standard sur sa sortie standard. Elle peut donc lire le fichier morceaux par morceaux et les afficher au fur et à mesure. Supposons que fichier.txt contient AB :
$ cat < fichier.txt >> fichier.txt
On évitera toujours de manipuler le même fichier en entrée et en sortie. Il vaut mieux rediriger vers un fichier temporaire, puis renommer ce dernier (avec la commande mv).
Sous Unix, chaque commande renvoie un code de
sortie (un entier entre 0 et 255).
Note : lors de l'écriture d'un programme C (ou C++) c'est
le fameux int renvoyé par la fonction :
int main(int argc, char **argv) { … }
Par convention, un code de 0 signifie terminaison normale, un code différent de 0 une erreur. On peut enchaîner des commandes de plusieurs façons :
Dans un fichier « counter.c » (attention c'est du pseudo C)
int count = 0;
int exit = 0;
void display() {
while (exit == 0) {
sleep (3);
printf("%i\n", count);
}
}
void listen() {
while (exit == 0) {
wait_connect(80);
count++;
}
}
void main () {
run_function(display);
run_function(listen);
while (getc () != '\n') { };
exit = 1;
return;
}
Compilation
gcc -o counter.exe counter.c
Le fichier « counter.exe » est un
exécutable (fichier binaire contenant du code machine)
./counter.exe ← il faut la permission +x sur le fichier
Le contenu de l'exécutable est copié en mémoire et le processeur
commence à exécuter la première instruction du programme.
listen
Les threads partagent leur mémoire (variables communes)
(différence: les processus ne partagent pas leur espace mémoire)
C'est le gestionnaire de processus qui décide quel
programme a la main et pour combien de temps (priorité aux
tâches critiques par exemple)
Le système d'exploitation stocke pour chaque processus un
ensemble d'informations, le PCB (Process Control Block).
Le PCB contient:
Un processus change d'état au cours de son exécution
Nouveau | le processus est en cours de création |
Exécution | le processus s'exécute |
En attente | le processus attend un évènement particulier (saisie au clavier, écriture sur le disque, …) |
Prêt | le processus est prêt à reprendre son exécution et attend que l'OS lui rende la main |
terminé | le processus a fini son exécution |
L'OS détermine et modifie l'état d'un processus:
Permet d'avoir des informations sur les processus en cours
d'exécution (voir « man ps » pour les
options):
$ ps -o user,pid,state,cmd x
USER PID S CMD
…
kim 27030 Z [chrome] <defunct>
kim 27072 S /opt/google/chrome/chrome --type=renderer
kim 29146 S bash
kim 29834 S evince
kim 29858 S emacs cours.xhtml
kim 29869 R ps -o user,pid,state,cmd x
R | Running (en cours d'exécution) |
S | Interruptible sleep (en attente, interruptible) |
D | Uninterruptible sleep (en attente, non-interruptible) |
T | Stopped (interrompu) |
Z | Zombie (terminé mais toujours listé par le système) |
L'OS peut envoyer des signaux à un processus. Sur réception d'un signal, un processus peut interrompre son comportement normal et exécuter son gestionnaire de signal. Quelques signaux:
Nom | Code | Description |
---|---|---|
INT/TERM | 2,15 | demande au processus de se terminer |
QUIT | 3 | interrompt le processus et produit un dump |
KILL | 9 | interrompt le processus immédiatement |
SEGV | 11 | signale au processus une erreur mémoire |
STOP | 24 | suspend l'exécution du processus |
CONT | 28 | reprend l'exécution d'un processus suspendu |
Un processus est lié au terminal dans lequel il est
lancé. Si on exécute un programme dans un terminal et que le
processus ne rend pas la main, le terminal est bloqué
$ gedit
On peut envoyer au processus le signal STOP en
tapant ctrl-Z
dans le terminal:
$ gedit
^Z
[1]+ Stopped gedit
Le processus est suspendu, la fenêtre est gelée (ne répond plus).
On peut reprendre l'exécution du programme de deux
manières:
$ fg
Reprend l'exécution du processus et le remet en avant plan (terminal
bloqué)
$ bg
Reprend l'exécution du processus et le remet en arrière plan (terminal
libre)
On peut lancer un programme
directement en arrière plan en faisant:
$ gedit &
On peut envoyer un signal à un
processus avec la commande « kill [-signal] pid »
$ kill -9 2345
Le terminal et le processus sont liés par trois fichiers spéciaux:
Dans le shell, on peut utiliser les
opérateurs <, >
et 2> pour récupérer le contenu
de stdin, stdout
et stderr:
$ sort < toto.txt
$ ls -l > liste_fichiers.txt
$ ls -l * 2> erreurs.txt
Dans le shell, l'opérateur | permet
d'enchaîner la sortie d'un programme avec l'entrée d'un
autre:
$ ls -l *.txt | sort -n -r -k 5 | head -n 1
-rw-rw-r 1 kim kim 471 Sep 14 16:25 bd.txt
-rw-rw-r 1 kim kim 234 Sep 15 17:46 foo.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
-rw-rw-r 1 kim kim 471 Sep 14 16:25 bd.txt
-rw-rw-r 1 kim kim 234 Sep 15 17:46 foo.txt
-rw-rw-r 1 kim kim 1048576 Sep 24 09:20 large.txt
Quelques exemples de commandes problématiques :
$ sort fichier.txt > fichier.txt
fichier.txt devient vide !
Il est ouvert en écriture et tronqué avant l'exécution de la commande.
$ sort < fichier.txt > fichier.txt
fichier.txt devient vide !
Il est ouvert en écriture et tronqué avant l'exécution de la commande.
$ sort < fichier.txt >> fichier.txt
fichier.txt contient son contenu original, suivi de son contenu trié !
$ cat < fichier.txt >> fichier.txt
fichier.txt est rempli jusqu'à
saturation de l'espace disque !
La commande sort doit trier son entrée
standard. Elle doit donc la lire intégralement avant de
produire la moindre sortie. Pour
$ sort < fichier.txt >> fichier.txt
on a donc :
La commande cat ré-affiche son entrée
standard sur sa sortie standard. Elle peut donc lire le
fichier morceaux par morceaux et les afficher au fur et à
mesure. Supposons que fichier.txt
contient AB :
$ cat < fichier.txt >> fichier.txt
On évitera toujours de manipuler le même fichier en entrée et en sortie. Il vaut mieux rediriger vers un fichier temporaire, puis renommer ce dernier (avec la commande mv).
Sous Unix, chaque commande renvoie un code de
sortie (un entier entre 0 et 255).
Note : lors de l'écriture d'un programme C (ou C++) c'est
le fameux int renvoyé par la fonction :
int main(int argc, char **argv) { … }
Par convention, un code de 0 signifie terminaison normale, un code différent de 0 une erreur. On peut enchaîner des commandes de plusieurs façons :
Mentalité Unix beaucoup de petits programmes spécifiques, que l'on combine au moyen de scripts pour réaliser des actions complexes. Exemple de fichier script:
#!/bin/bash
for i in img_*.jpg
do
base=$(echo "$i" | cut -f 2- -d '_')
nouveau=photo_"$base"
if test -f "$nouveau"
then
echo "Attention, le fichier $nouveau existe déjà"
continue
else
echo "Renommage de $i en $nouveau"
mv "$i" "$nouveau"
fi
done
Si un fichier texte (quel que soit son extension), commence par les caractères #!/chemin/vers/un/programme, on peut rendre ce fichier exécutable (chmod +x). Si on l'exécute, le contenu du fichier est passé comme argument à programme (qui est généralement un interpréteur)
#!/bin/bash signifie que le corps du fichier est passé au programme bash qui est l'interprète de commande (le shell).
On peut définir des variables au moyen de la notation
VARIABLE=contenu
et on peut utiliser la variable
avec la notation $VARIABLE
i=123
j="Ma super chaine"
TOTO=titi
echo $TOTO
exemple d'utilisation: echo $j $i $TOTO
affiche « Ma super chaine 123 titi »
Les boucles for ont la syntaxe:
for VARIABLE in elem1 ... elemn
do
....
done
chaque elemi est expansé (comme une ligne de
commande) avant l'évaluation de la boucle:
for i in *.txt
do
echo $i est un fichier texte
done
On peut quitter une boucle prématurément en utilisant break
et passer directement au tour suivant avec continue
La syntaxe est :
if commande
then
...
else
...
fi
commande est évaluée. Si elle se termine avec succès,
la branche then est prise. Si elle se termine avec un code
d'erreur, la branche else est prise. On peut utiliser la
commande test qui permet de tester plusieurs conditions
(existance d'un fichier, égalités de deux nombres, ...) et se termine
par un succès si le teste est vrai et par un code d'erreur dans le
cas contraire
On regarde tour à tour si fichier1.txt, fichier2.txt, ... existent :
for i in 1 2 3 4 5 6
do
if test -f "fichier$i".txt
then
echo le fichier "fichier$i".txt existe
fi
done
Il est pratique de pouvoir mettre l'affichage d'une commande
dans une variable. On utilise $( commande ... ):
MESFICHIER=$(ls *.txt)
for i in $MESFICHIER
do
echo Fichier: $i
done
Attention à la présence de guillemets autour des variables. S'il y a
f1.txt et f2.txt dans le répertoire courant:
MESFICHIER=$(ls *.txt)
for i in $MESFICHIER
do
echo Fichier: $i
done
affiche:
Fichier: f1.txt
Fichier: f2.txt
MESFICHIER=$(ls *.txt)
for i in "$MESFICHIER"
do
echo Fichier: $i
done
affiche:
Fichier: f1.txt f2.txt
On peut effectuer des calculs arithmétiques au moyen de :
$(( … expression … ))
Par exemple :
echo $(( 1 + 2 + 9 + 10 + 20))
affiche 42 sur la sortie standard. Il est possible
d'utiliser les
opérations +, -, *, /
et % sur les entiers. Les entiers sont signés et leur
taille dépend de l'architecture de la machine (32 ou 64 bits).
On peut bien-sûr réutiliser des variables dans les expressions.
X=3
Y=4
Z=$(( $X + $Y ))
echo $(( $Z * 2 ))
affiche 14 sur la sortie standard.
Certaines variables sont prédéfinies par le shell :
Une variable non-définie est automatiquent remplacée par
la chaîne de caractères vide sans provoquer
d'erreur.
Un script hérite d'une copie de toutes les variables du shell dans
lequel il est lancé.
Une variable définie dans un script ne survit pas à ce
dernier
La directive export permet de définir des
variables qui survivent à un script ou de modifier des variables
du shell depuis un script.
Un daemon (prononcé démon) est un processus qui non-interactif qui tourne en tâche de fond (pas d'entrée/sortie sur le terminal, pas d'interface graphique, …). On communique avec ce processus via des signaux ou en lisant ou écrivant dans des fichiers ou connexions réseau. Le plus souvent, leur but est de fournir un service
Exemple de scénario: « Les utilisateurs doivent interagir avec le matériel. L'accès au matériel demande des droits administrateur. »
Nom | Description |
---|---|
sshd | shell distant sécurisé |
crond | exécution périodique de programmes |
cupsd | serveur d'impressions |
pulseaudio | serveur de son (mixe les sons des différentes applications) |
udevd | détection de matériel hotplug |
nfsd | serveur de fichier réseau |
smtpd | livraison des e-mail |
httpd | serveur de pages Web |
Des processus clients communiquent avec le serveur à travers le réseau. Les clients sont indépendant et ne communiquent pas entre eux. Attention plusieurs clients peuvent se trouver su la même machine physique!
Exemples: serveur de bases de données, serveur mail, serveur Web, terminal de carte bancaire, …