L3 MIASHS 2016-2017 - Déroulement réel des cours

La « pensée » du Dilun, d'an 20 a viz Du 2017 , 23h56m03s :
Je peux résister à tout, sauf à la tentation

Semaine du lendi 12 septemb' 2016 : CM n°1 (Cumul=1,5h)

Dernière modification : 12/9/2016

Semaine du lendi 12 septemb' 2016 : TD n°1 (Cumul=1,5h)

Dernière modification : 17/10/2016

Semaine du lendi 19 septemb' 2016 : CM n°2 (Cumul=3h)

Exercice de réflexion

Pourquoi le titre d'un article récent de FranceTVInfo (Piratage de TV5 Monde par des jihadistes : "Du jamais-vu en trente ans" — 8 avril 2015) est-il au minimum une grosse ânerie ?
Pour vous aider dans vos réflexions, allez consulter l'historique du web sur Wikipedia.

Octet et multiples

(Voir « Préfixes du système international d'unités » sur Wikipédia.)
Extrait de la page que Wikipedia consacre à l'octet :

Traditionnellement, les préfixes « kilo », « méga », « giga », etc. dans le monde informatique, ne représentaient pas une puissance de 10 (103 = 1 000), mais une puissance de 2 (210 = 1 024) (plus précisément, il s'agit de puissance de 103 et 210, car la notion de multiple porte sur l'exposant 3 ou 10). Cependant cette tradition violait les normes en vigueur pour les autres unités, y compris le bit, et n'est même pas appliquée uniformément aux octets, notamment dans la mesure de la capacité des disques durs. Une nouvelle norme a donc été créée pour noter les multiples de 210 = 1 024 : les « kibi », « mébi », « gibi », etc.

L'usage traditionnel reste largement en vigueur chez les professionnels comme le grand public, même si c'est en contradiction avec les recommandations SI qui définissent clairement d'autres préfixes. L'usage des préfixes binaires reste très confidentiel et ne se répand presque pas dans le langage courant, alors que les valeurs représentées par ces unités en puissance de 2 sont très utilisées dans les applications, notamment les systèmes d'exploitation. Cependant, leur utilisation commence à se répandre, notamment dans le monde du logiciel libre, comme dans les systèmes d'exploitation libres de type GNU/Linux.

Cette distinction (entre préfixes binaires et décimaux) est anécessaire, car la confusion entre les deux séries de coefficients est utilisée depuis longtemps par les fabricants de disques durs. Le fait que l'usage (pour une même capacité) de préfixes en puissances de 10 permette d'afficher commercialement des valeurs supérieures à celles données par les puissances de 2 peut introduire une erreur d'appréciation de la part d'utilisateurs non avertis. Ainsi, un disque dur de 100 gigaoctets (100×109 octets) contient le même nombre (à l'erreur d'arrondi près) d'octets qu'un disque de 93,13 gibioctets (93,13×230 octets).

Attention : les vitesses de transferts internet sont souvent comptées en bits, pas en octets...

Exercice

  1. Les premiers modems de qualité fonctionnaient en 56K (56 kb/s !). Combien fallait-il de temps pour télécharger un CD converti en MP3 (environ 50 à 60 Mo, vous pouvez choisir 56Mo pour faciliter les calculs) ?
    56K signifie une vitesse de transfert de 56Kbits par seconde, c'est-à-dire 56 000 bits par seconde.
    Il y a 56×1 000 000×8 bits dans 56Mo.
    Ça fait donc 8 000 secondes. C'est-à-dire environ 2 heures et 22 minutes.
  2. Même question pour télécharger le même CD avec une liaison ADSL haut débit ? On peut compter en moyenne entre 5 et 10 Mb/s (vous pouvez prendre 5,6 Mb/s pour faciliter les calculs).
    5,6Mb/s signifie une vitesse de transfert de 5,6×1000 000 bits par seconde.
    Il y a toujours 56×1 000 000×8 bits dans 56Mo.
    Ça fait donc 80 secondes
  3. Le débit montant est en général beaucoup plus faible que le débit descendant. Il est en moyenne entre 500kb/s et 1Mb/s pour une liaison ADSL classique. Combien de temps pour uploader le même CD ? (Comme les fois précédentes, on va choisir une valeur qui nous facilite les calculs : 560Kb/s.)
    560Kb/s c'est 10 fois plus lent que 5,6Mb/s. Il faudra donc dix fois plus de temps, c'est-à-dire 800 secondes, ou, si préférez, un peu plus de 13 minutes.
    Attention : pour une liaison par fibre optique, la vitesse peut être couramment 10 fois plus grande, et le débit montant est souvent dans le même ordre de grandeur que le débit descendant.
  4. Et si on se pose les mêmes questions pour une vidéo de 560 Mo ?
    On a une taille de fichier 10 fois plus grande, il faudra donc 10 fois plus de temps :
    • plus de 20 heures télécharger la vidéo avec un modem 56K,
    • 13 minutes pour télécharger la vidéo en ADSL,
    • un peu plus de 2 heures pour l'uploader en ADSL.
Attention : toutes ces valeurs de débit sont très théoriques, elles sont rarement atteintes en réalité. Le débit baisse par exemple si vous n'êtes pas seul sur la ligne (plusieurs ordinateurs, une télé, etc.).

Compléments

  • Retours et compléments sur le codage de l'information (binaire), en particulier le codage des caractères (ASCII, unicode, etc.)
    Pourquoi l'octet comme base de calcul ?
    D'où : une tentative d'en avoir une représentation intuitive (1ko=1 page de texte, 1Mo=1 000 pages de texte, 1Go=1 000 000 pages de texte, etc...).
    Qu'est-ce que ça change un OS 64 bits par rapport à un OS 32 bits ?
  • Les unités de mesure de fréquence : hertz et multiples.
  • Codage d'une image, codage d'une couleur, compression avec ou sans perte.
Dernière modification : 14/10/2016

Semaine du lendi 19 septemb' 2016 : TD n°2 (Cumul=3h)

Utilisation de l'interface graphique dans la manipulation des fichiers

  1. Dans votre répertoire personnel, créer un répertoire TP1. Puis créer un répertoire tp1. Remarque ?
  2. Recopier dans le répertoire TP1 tout le contenu du répertoire /usr/sbin/.
  3. Déplacer dans le répertoire tp1 tout le contenu du répertoire /usr/sbin/. Remarque ?
  4. Renommer le répertoire tp1 en TP2, y créer un (sous-)répertoire sbin, et y déplacer tous les fichiers de TP1.
  5. Supprimer le répertoire TP2.

Manipulations de base dans une fenêtre de commandes

  • Lancer une fenêtre de commandes, la fermer, des onglets...
  • Exécuter une commande sous linux : dans un terminal, un écran texte.
  • Les touches pour gérer le shell. En plus des touches classiques (flèches droite et gauche, SUPPR et BACKSPACE) pour se déplacer et modifier, on a aussi :
    • ORIG (ou HOME) et FIN pour aller directement en début et fin de ligne de commandes.
    • Flèches haut et bas (se déplacer dans l'historique des commandes).
    • CTRL + U (efface depuis le curseur jusqu'au début de la ligne de commande, et place dans le presse-papier).
    • CTRL + K (efface depuis le curseur jusqu'à la fin de la ligne de commande, et place dans le presse-papier).
    • CTRL + Y (recopie le presse-papier sur la ligne de commande depuis la position du curseur).
      Ne pas oublier le bouton du milieu de la souris (la molette), bien pratique sous linux pour le sélectionner/coller (pas besoin de copier).
    • TAB (complétion du nom d'un fichier présent dans le répertoire actif).
    • CRTL + C (interrompt la commande en cours).
    • CTRL + ALT + SUPPR (arrête la session, mais ne marche pas dans toutes les interfaces graphiques).
  • clear (efface l'écran).
  • Comment se déplacer dans l'arborescence (cd). Chemin absolu et chemin relatif.
    Comment savoir où on est (pwd).
    Comment monter dans le répertoire père. Comment descendre dans un répertoire fils. Comment revenir au répertoire home.
    Comment lister le contenu d'un répertoire (ls).
  • Obtenir des informations : man (ou http://man.developpez.com/), apropos, whatis, file, who, whoami.
  • Les commandes de gestion des processus.
    • top (affiche l'utilisation des ressources par les processus en temps réel)
    • ps (process search)
      • ps
      • ps -l (affichage long des processus de l'utilisateur )
      • ps -e (affiche les processus en cours)
      • ps -ef (affiche les processus en cours en détail)
      • ps -efl (affichage long et en détail des processus en cours)
      • ps -ef | grep user
      • ps -aux
      • ps -aefx
      • ps -aef | grep "vi"
      • ps -aux | wc -l
    • kill (envoie un signal à un processus)
      • kill PID (demande la fermeture propre du processus PID)
      • kill -9 PID (ferme autoritairement le processus PID, ce qui peut provoquer des pertes de données et/ou la création de fichier d'erreur, les fichiers « core » ainsi créés peuvent être de très grande taille parce qu'ils contiennent des images de toutes les données traitées par le processus bloqué).
    • killall
      • killall NOM_DU_PROCESSUS pour supprimer les processus proliférants (« spawning process ») comme telnet, lpd qui se reproduisent à chaque nouvelle requête.
  • Aller voir les répertoires des autres si c'est possible.
    Parenthèse sur les droits d'accès. On verra plus tard comment les changer.
    Vocabulaire : Selon que vous veniez du monde windows ou du monde linux, le vocabulaire ne sera peut-être pas identique : on dira « dossier » et « document » dans le monde windows, tandis qu'on dira plutôt « répertoire » et « fichier » dans le monde linux ; ces différences ne doivent pas vous perturber, les mots sont différents mais les concepts sont identiques. Vous pouvez considérer sans aucun risque que « dossier » et « document » sont respectivement synomymes de « répertoire » et « fichier ».
  • Créer des répertoires (mkdir), des fichiers, puis les effacer (rm et rmdir). Caractères joker, ou génériques (* et ?).
    En profiter pour vérifier les droits et l'impossibilité d'effacer les fichiers des autres.
Dernière modification : 17/10/2016

Semaine du lendi 26 septemb' 2016 : CM n°3 (Cumul=4,5h)

Parallélisme ou multitâche ?

Dans l'ordinateur...

Architecture
  simplifiée d'un ordinateur
Architecture simplifiée d'un ordinateur

En simplifiant (un peu) moins, ce qui compose un processeur [https://fr.wikipedia.org/wiki/Processeur] :

  • UAL, Unité arithmétique et logique [https://fr.wikipedia.org/wiki/Unit%C3%A9_arithm%C3%A9tique_et_logique] : prend en charge les calculs arithmétiques élémentaires et les tests.
  • Unité de contrôle, ou séquenceur [https://fr.wikipedia.org/wiki/Unit%C3%A9_de_contr%C3%B4le] : permet de synchroniser les différents éléments du processeur.
  • Compteur ordinal [https://fr.wikipedia.org/wiki/Compteur_ordinal] : contient l’adresse mémoire de l’instruction en cours d’exécution ou de la suivante, selon l'architecture.
  • Registre d’instructions : contient l’instruction en cours de traitement.
  • L’horloge qui synchronise toutes les actions de l’unité centrale.
  • Trois types de bus :
    • un bus de données, qui définit la taille des données pour les entrées/sorties, dont les accès à la mémoire ;
    • un bus d'adresse, qui permet, lors d'une lecture ou une écriture, d'envoyer l'adresse où elle s'effectue, et donc définit le nombre de cases mémoire accessibles ;
    • un bus de contrôle permet la gestion du matériel, via les interruptions.

Multitâche

(Source : Multitâche sur Wikipedia [https://fr.wikipedia.org/wiki/Multit%C3%A2che] )

Le fonctionnement interne d'un ordinateur est fondamentalement séquentiel, contrôlé par le séquenceur. Mais plusieurs méthodes existent pour (nous donner l'illusion) que plusieurs choses se passent en même temps. La première en date a été le multitâche (Gamma 60 [https://fr.wikipedia.org/wiki/Gamma_60], de Bull, en 1958).

Un système d'exploitation est multitâche s’il permet d’exécuter, de façon apparemment simultanée, plusieurs programmes informatiques.
La simultanéité apparente est le résultat de l’alternance rapide d’exécution des processus présents en mémoire.
Le passage de l’exécution d’un processus à un autre est appelé commutation de contexte. Ces commutations peuvent être initiées par les programmes eux-mêmes (multitâche coopératif) ou par le système d’exploitation lors d’événements externes (multitâche préemptif).

Les systèmes multitâches se sont ensuite répandus dans le courant des années 1960 dans une double déclinaison :

  • systèmes à temps partagé : ils permettent à plusieurs utilisateurs de travailler sur la même machine (pour des questions de rentabilité, le matériel étant extrêmement coûteux) ;
  • systèmes temps réel pour la commande de processus industriels : de nombreux programmes de petite taille s'exécutent à la réception d'événements externes (acquisition de données, alerte d'un équipement...) dans un mode de gestion par interruptions avec priorités d'exécution.

Bien que, au départ, le multitâche ait été conçu pour permettre à plusieurs utilisateurs d’utiliser le même ordinateur, il est apparu très rapidement qu’il était très pratique même pour un seul utilisateur. Utiliser son traitement de texte favori tout en naviguant sur le Web est de nos jours une caractéristique incontournable.

Une autre utilité du multitâche provient du fait qu’il est plus facile de concevoir et d’écrire plusieurs programmes simples, plutôt qu’un seul programme capable de tout faire, puis de les faire coopérer pour effectuer les tâches nécessaires.

Les algorithmes implémentant le multitâche ont été raffinés au cours du temps. Les systèmes modernes peuvent gérer des processus avec des priorités différentes ainsi que des ordinateurs comportant de un à quelques centaines de processeurs.

Multitâche coopératif

Le multitâche coopératif est une forme simple de multitâche où chaque processus doit explicitement permettre à une autre tâche de s’exécuter. Il a été utilisé, par exemple, dans les produits Microsoft Windows jusqu’à Windows 3.11 ou dans Mac OS jusqu’à Mac OS 9. Cette approche simplifie l’architecture du système d’exploitation mais présente plusieurs inconvénients :

  • Si un des processus ne redonne pas la main à un autre processus, par exemple si le processus est buggé, le système entier peut s’arrêter.
  • Le partage des ressources (temps CPU, mémoire, accès disque, etc.) peut être inefficace.
  • Le multitâche coopératif est une forme de couplage fort.

Multitâche préemptif

Pour remédier à cette situation, les systèmes grand public ont évolué pour utiliser une approche nommée « multitâche préemptif ».

Dans un tel système, le processeur signale au système d’exploitation que le processus en cours d’exécution doit être mis en pause pour permettre l’exécution d’un autre processus. Le système doit alors sauver l’état du processus en cours (le compteur ordinal, les valeurs des registres) ; le processus est placé dans une file d’attente ; lorsqu’il est en bout de file, son contexte d’exécution est restauré. À la différence du « multitâche coopératif », du point de vue des programmes préemptés, la commutation de contexte est transparente.

Unix (1969) et ses dérivés (BSD en 1977, Linux en 1991, ...) sont des systèmes basés sur le multitâche préemptif.

Sinclair QDOS (1984), AmigaOS (1985), NeXTSTEP (1989) ou BeOS (1991) sont des systèmes multitâches préemptif depuis leur naissance.
D’autres systèmes d’exploitation le sont devenus comme Windows (avec Windows NT 3.1 en 1993 pour les professionnels et Windows 95 en 1995 pour le grand public) et MacOS X en 2001.

Préemptif ou coopératif ?

Le multitâche préemptif est plus robuste que le multitâche coopératif : une tâche ne peut bloquer l’ensemble du système. Le système d’exploitation peut aussi utiliser plus efficacement les ressources disponibles, par exemple si des données sont disponibles via un périphérique d’entrée, le processus devant traiter ces données peut être immédiatement activé.
De plus, une tâche en attente de données ne consommera pas de temps processeur avant que ses données ne soient réellement disponibles.

Parallélisme

(Source : Parallélisme sur Wikipedia [https://fr.wikipedia.org/wiki/Parall%C3%A9lisme_%28informatique%29] )

Le parallélisme consiste à mettre en œuvre des architectures permettant de traiter des informations de manière simultanée. Ces techniques ont pour but de réaliser le plus grand nombre d'opérations en un temps le plus petit possible.

Les architectures parallèles sont devenues le paradigme dominant pour tous les ordinateurs depuis les années 2000. En effet, la vitesse de traitement qui est liée à l'augmentation de la fréquence des processeurs connait des limites. La création de processeurs multi-cœurs, traitant plusieurs instructions en même temps au sein du même composant, résout ce dilemme pour les machines de bureau depuis le milieu des années 2000.

Certains types de calculs se prêtent particulièrement bien à la parallélisation : la dynamique des fluides, les prédictions météorologique, la modélisation et simulation de problèmes de dimensions plus grandes, le traitement de l'information et l'exploration de données, le décryptage de messages, la recherche de mots de passe, le traitement d'images ou la fabrication d'images de synthèse, tels que le lancer de rayon, l'intelligence artificielle et la fabrication automatisée.

Mais tout ne peut pas être parallélisé. Prenons par exemple ces deux fonctions :

function Dep(a, b) :
  c = a * b
  d = 2 * c
function NoDep(a, b) :
  c = a * b
  d = 2 * b
  e = a + b

La première fonction n'est clairement pas parallélisable, car sa deuxième instruction dépend du résultat de la première et devra attendre que celle-ci soit terminée pour s'exécuter.
La deuxième fonction est par contre bien parallélisable, car ses trois instructions sont indépendantes les unes des autres.

Quel parallélisme ?

On peut distinguer trois principaux types de parallélisme : les pipelines, les ordinateurs multi-processeurs, et les processeurs multi-cœurs.

Pipelines

Un programme informatique est, par essence, un flux d'instructions exécuté par un processeur. Chaque instruction nécessite plusieurs cycles d'horloge, l'instruction est exécutée en autant d'étapes que de cycles nécessaires :

  • IF (Instruction Fetch) charge l'instruction à exécuter dans le pipeline.
  • ID (Instruction Decode) décode l'instruction et adresse les registres.
  • EX (Execute) exécute l'instruction (par la ou les unités arithmétiques et logiques).
  • MEM (Memory), dénote un transfert depuis un registre vers la mémoire dans le cas d'une instruction du type STORE (accès en écriture) et de la mémoire vers un registre dans le cas d'un LOAD (accès en lecture).
  • WB (Write Back) stocke le résultat dans un registre. La source peut être la mémoire ou bien un registre.

Les microprocesseurs séquentiels exécutent l'instruction suivante lorsqu'ils ont terminé la première.

En supposant que chaque étape met 1 cycle d'horloge pour s'exécuter, il faut normalement 5 cycles pour exécuter une instruction, 15 pour 3 instructions :

Pipeline
Séquençage des instructions dans un processeur sans pipeline. Il faut 15 cycles pour exécuter 3 instructions.
(source : Wikipedia [https://fr.wikipedia.org/wiki/Pipeline_%28architecture_des_processeurs%29])

Dans le cas du parallélisme d'instruction, le microprocesseur peut traiter plusieurs de ces étapes en même temps pour plusieurs instructions différentes, car elles ne mobilisent pas les mêmes ressources internes. Autrement dit, le processeur exécute en parallèle des instructions qui se suivent à différents stades d'achèvement. Cette file d'exécution s'appelle un pipeline. Ce mécanisme a été mis en œuvre pour la première fois dans les années 1960 par IBM.

Pipeline
Séquençage des instructions dans un processeur doté d'un pipeline à 5 étages.
Il faut 9 cycles pour exécuter 5 instructions.
À t = 5, tous les étages du pipeline sont sollicités, et les 5 opérations ont lieu en même temps.
(source : Wikipedia [https://fr.wikipedia.org/wiki/Parall%C3%A9lisme_%28informatique%29])

Multi-processeurs

L'idée de faire cohabiter deux processeurs dans la même machine date des années 1960, le D825 de Burroughs Corporation commercialisé en 1962 est le premier ordinateur multi-processeur, mais ce système n'était pas parallèle. Il a fallu attendre 1969 pour que Honeywell produise le premier ordinateur qui dispose de processeurs fonctionnant réellement en parallèle. Les huit processeurs de cette machine de la série Honeywell 800 fonctionnaient de manière symétrique (ou SMP), c'est-à-dire que tous les processeurs ont la même fonction et les mêmes capacités. Ce ne fut pas le cas de toutes les machines, DEC et le MIT ont développé dans les années 1970 une technologie asymétrique, mais elle a été abandonnée dans les années 1980. Peu de machines ont utilisé ce principe, même si certaines ont eu du succès comme les VAX.

Multi-cœurs

Un microprocesseur multi-cœur (multi-core en anglais) est un processeur possédant plusieurs cœurs physiques fonctionnant simultanément. Il se distingue d'architectures plus anciennes où un processeur unique commandait plusieurs circuits de calcul simultanés.

Un cœur physique est un ensemble de circuits capables d’exécuter des programmes de façon autonome. Toutes les fonctionnalités nécessaires à l’exécution d'un programme sont présentes dans ces cœurs : compteur ordinal, registres, unités de calcul, etc. Des caches sont définis pour chaque processeur ou partagés entre eux.

Cas particuliers

  • Coprocesseurs
    Les coprocesseurs sont des unités destinées à fournir des fonctionnalités supplémentaires au processeur, ou des circuits spécialisés pour des applications particulières. Certaines de ces applications sont facilement parallélisables, comme les calculs graphiques. Beaucoup de coprocesseurs graphiques actuels permettent aussi de réaliser des calculs parallèles sans qu'il s'agisse nécessairement de création d'image.
  • Systèmes à plusieurs machines
    Pour faire fonctionner en parallèle un plus grand nombre de processeurs, on peut utiliser plusieurs machines qui communiquent ensemble via un réseau. Selon les cas, il peut s'agir d'un réseau d'interconnexion spécialement conçu ou d'internet, comme pour BOINC [https://fr.wikipedia.org/wiki/Berkeley_Open_Infrastructure_for_Network_Computing], mis au point par l'université de Californie à Berkeley, elle-même créatrice du projet de recherche d'intelligence extraterrestre SETI@home [https://fr.wikipedia.org/wiki/SETI@home].

Lectures pour aller plus loin...

Multitâche

Parallélisme

Multi-cœurs

Dernière modification : 23/10/2016

Semaine du lendi 26 septemb' 2016 : TD n°3 (Cumul=4,5h)

Pour compléter le cours précédent

Manipulations de base dans une fenêtre de commandes

  • Copier des fichiers (cp) : entre ses propres répertoires, depuis les répertoires des autres. Copier des répertoires.
  • Renommer un fichier, un répertoire (mv). Déplacer (mv).

Exercice n°1

  1. Dans votre répertoire personnel, créer un répertoire TP1. Puis créer un répertoire tp1. Remarque ?
    cd
    mkdir TP1
    mkdir tp1

    On peut remarquer que ça ne pose pas de problème, les majuscules et minuscules sont réellement différenciées.
  2. Recopier dans le répertoire TP1 tout le contenu du répertoire /usr/sbin/.
    cp /usr/sbin/* TP1
  3. Déplacer dans le répertoire tp1 tout le contenu du répertoire /usr/sbin/. Remarque ?
    mv /usr/sbin/* tp1
    Ça ne marche pas... On ne peut pas modifier/effacer/déplacer les fichiers systèmes.
  4. Renommer le répertoire tp1 en TP2, y créer un (sous-)répertoire sbin, et y déplacer tous les fichiers de TP1.
    mv tp1 TP2
    mkdir TP2/sbin
    mv TP1/* TP2/sbin
  5. Supprimer les répertoires TP1 et TP2.
    rmdir TP1
    rm -rf TP2

Les commandes linux, suite

  • Créer un fichier vide, modifier la date de dernière modification d'un fichier existant (touch).
  • history (affiche la liste des commandes de historique) :
    • history -c (efface la liste de l'historique)
    • !! (rappelle de la commande précédente équivalent à « !-1 »)
    • !x (rappelle de la commande n°x)
    • !-x (rappelle la commande n°x dans l'ordre inversé, en commençant par la fin)
    • !cp (rappelle la dernière commande qui commence par « cp »)
  • Afficher le contenu d'un fichier :
    • cat (et tac en ordre inverse)
    • Afficher le début d'un fichier : head. Afficher la fin : tail.
    • Afficher écran par écran : more et less.
    • Numérotation des lignes : nl ou cat -n.
    • Affichage avec tri : sort.
  • Les pipes («|»).
    Exemple : tac script.txt | nl | head -n5 | tail -n3 | tac

Exercice n°2

  1. Créez, dans votre répertoire personnel, un répertoire CommandesLinux contenant l'arborescence suivante :
    .
    ├── couleur
    │   └── froide
    └── forme
        ├── angle
        └── courbe
    cd
    mkdir CommandesLinux
    mkdir CommandesLinux/couleur
    mkdir CommandesLinux/couleur/froide
    mkdir CommandesLinux/forme
    mkdir CommandesLinux/forme/angle
    mkdir CommandesLinux/forme/courbe

    ou
    cd
    mkdir CommandesLinux CommandesLinux/couleur CommandesLinux/couleur/froide CommandesLinux/forme CommandesLinux/forme/angle CommandesLinux/forme/courbe

    ou
    cd
    mkdir CommandesLinux
    cd CommandesLinux
    mkdir couleur
    mkdir forme
    cd couleur
    mkdir froide
    cd ../forme
    mkdir angle
    mkdir courbe
  2. Copiez le fichier /etc/services dans votre répertoire CommandesLinux.
    En étant dans le répertoire CommandesLinux :
      cp -R /etc/services .
  3. À qui (et à quel groupe) appartient le fichier que vous venez de copier ? Quelle est sa date de sa dernière modification ?
    Il vous appartient, et sa date de modification est l'heure de la copie.
    Ces informations sont accessibles par la commande ls -lah
  4. Créez dans le répertoire CommandesLinux les fichiers ne contenant aucune donnée et dont les noms sont : rond.txt, triangle.txt, carre.txt, rectangle.txt, vert.txt et bleu.txt.
    touch rond.txt triangle.txt carre.txt rectangle.txt vert.txt bleu.txt
  5. Déplacez le fichier rond.txt dans le répertoire courbe et les fichiers triangle.txt, carré.txt, rectangle.txt dans le répertoire angle.
    mv rond.txt forme/courbe
    mv triangle.txt carre.txt rectangle.txt forme/angle
  6. Déplacez les fichiers vert.txt et bleu.txt dans le répertoire froide.
    mv vert.txt bleu.txt couleur/froide
  7. Allez dans le répertoire couleur et afficher le contenu du répertoire de façon récursive.
    cd couleur
    ls -R
  8. Copier le répertoire froide sous le nom chaude.
    cp -R froide chaude
  9. Allez dans le répertoire chaude et renommez le fichier bleu.txt en rouge.txt, et vert.txt en jaune.txt.
    cd chaude
    mv bleu.txt rouge.txt
    mv vert.txt jaune.txt
  10. Remontez dans le répertoire CommandesLinux et renommez le répertoire couleur en peinture.
    cd ../..
    mv couleur peinture
  11. Affichez le contenu du fichier /etc/issue. Que contient-il ?
    cat /etc/issue
    Il contient le message affiché lors d'une connexion sur un terminal.
  12. Affichez page par page le contenu du fichier /etc/services. Que contient-il ?
    more /etc/services ou less /etc/services
    Il fournit une correspondance entre un nom intelligible décrivant un service Internet et l'ensemble numéro de port/protocole utilisé.
    Chaque programme réseau devrait consulter ce fichier pour obtenir le numéro de port et le protocole sous-jacent au service qu'il fournit.
Dernière modification : 17/10/2016

Semaine du lendi 3 octob' 2016 : CM n°4 (Cumul=6h)

Le contrôle n°1 aura lieu le mardi 18 octobre, pendant le CM n°6.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Les utilisateurs, les groupes, root, les droits

Linux est un système multi-utilisateurs. Cela signifie que plusieurs personnes peuvent travailler simultanément sur le même OS, en s'y connectant à distance notamment.

Puisque plusieurs utilisateurs peuvent être connectés à Linux en même temps, celui-ci doit avoir une excellente organisation dès le départ. Ainsi chaque personne a son propre compte utilisateur, et il existe un ensemble de règles qui disent qui a le droit de faire quoi.

  • Droits des utilisateurs
    Les droits d'un utilisateur de base sont :
    • voir et modifier ses propres fichiers ;
    • voir, sans pouvoir les modifier, certains fichiers du système ;
    • ni voir, ni modifier les fichiers des autres utilisateurs.
    Ces droits peuvent varier, et être modifiés. Ce sera le sujet de ce cours.
  • Un utilisateur particulier : root
    Il y a un utilisateur « spécial », root, appelé aussi superutilisateur, ou superuser en anglais.
    Celui-ci a tous les droits sur la machine. C'est l'administrateur du système.
    Contrairement à ce que pourrait laisser croire la phrase précédente, il s'agit rarement d'une personne unique. La plupart du temps plusieurs personnes ont accès à ce compte (il suffit d'en connaître le mot de passe). Il y a donc souvent plusieurs personnes physiques qui sont les administrateurs du système. Mais cela ne nous empêchera de parler dans la suite de L'utilisateur root, au singulier, sans tenir compte de l'identité réelle des personnes que cela concerne.
  • Qui peut être root ?
    • Tout utilisateur qui connaît le mot de passe.
      Dans les anciennes versions de linux, on pouvait se connecter, en tant que root, directement au démarrage de la machine.
      De plus en plus de distributions linux (par exemple ubuntu, mint, etc.) interdisent cela, et ne permettent la connexion comme root qu'aux utilisateurs déjà identifiés et connectés sous leur propre nom. On doit donc connaître deux mots de passe : celui d'un utilisateur, et celui de root. Cela ajoute un niveau de protection : il ne faut pas oublier qu'une fois connectée en tant que root, la personne qui est devant le clavier a absolument tous les droits sur l'intégralité du système. On comprend donc que l'accès en soit contrôlé sérieusement.
    • Les sudoers.
      Le fichier /etc/sudoers permet d'autoriser certains comptes à exécuter des commandes en tant que root, et ceci sans connaître le mot de passe root. Si votre compte est dans /etc/sudoers, il vous suffit d'utiliser la commande sudo en préfixe de toute commande pour pouvoir l'exécuter en tant que root.
      Si, par exemple, vous tapez la commande cat /etc/shadow (affiche le contenu du fichier /etc/shadow qui contient les mot de passe des utilisateurs, encodés en MD5 de manière à ce qu'on ne puisse pas les lire), il y a de fortes chances que cela vous soit refusé (sinon, votre machine n'est pas sécurisée). Par contre, si vous faites partie des sudoers, la commande sudo cat /etc/shadow fonctionnera.
  • La commande su
    La commande su (Switch User, appelée plus communément, à tort, Super Utilisateur) permet d'ouvrir une session avec l'identifiant d'un autre utilisateur, ou de démarrer un nouveau shell de connexion :
    • On l'utilise sous la forme « su toto » pour se connecter sous le nom de toto ; le système demande alors le mot de passe de toto (sauf si vous êtes déjà connecté comme utilisateur root : aucun mot de passe ne vous sera demandé pour utiliser su).
    • On l'utilise aussi sous la forme « su » (sans paramètre) pour se connecter comme root ; le système vous demande alors le mot de passe de root.
    • Sur les systèmes où la connexion directe comme root est interdite, il n'y a pas de mot de passe pour root ; dans ce cas on utilisera la commande sudo su, et ce sera votre mot de passe qui vous sera demandé. Il faut bien entendu être sudoer pour en avoir le droit.
    • On sort de la session root par CTRL D.
    sudo_sandwich.png, mar 2009
    (source : XKCD [http://xkcd.com/149/])
  • Les groupes
    Chaque utilisateur linux fait partie d'au moins un groupe, appelé son groupe initial ou son groupe primaire (en général un groupe qui a le nom de l'utilisateur et dont il est le seul membre), mais souvent aussi de plusieurs autres. C'est root qui décide des groupes auxquels va appartenir un utilisateur donné. Le but des groupes est de faciliter la gestion des permissions d'accès.
    Exemples de groupes possibles :
    • le groupe de ceux qui ont le droit d'utiliser les imprimantes,
    • le groupe de ceux qui ont le droit de gérer les imprimantes,
    • le groupe de ceux qui ont le droit d'utiliser le lecteur de DVD,
    • le groupe de ceux qui ont le droit de monter ue clef USB,
    • le groupe des sudoers,
    • etc.
  • Commandes à connaître sur les groupes
    • groups : affiche les groupes dont vous faites partie ; le premier de la liste est votre groupe courant ;
    • groups marcel : affiche les groupes dont Marcel fait partie ;
    • cat /etc/group : affiche la liste de tous les groupes ;
    • newgrp unGroupe : change votre groupe par défaut ; si le nom du groupe n'est pas précisé, reprend votre groupe initial ;

Les droits

La gestion des droits sur les fichiers linux se fait à trois niveaux parmi les utilisateurs (propriétaire, groupe, reste du monde), et à trois niveaux parmi les permissions possibles (lecture, écriture, exécution).

  • Permissions
    Permissions Littéral Numérique (octal) Numérique (binaire) Sur un fichier Sur un répertoire
    Read r 4 100 Le fichier peut être lu. Le répertoire peut être listé.
    Write w 2 010 Le contenu du fichier peut être modifié ou ses attributs modifiés. Dans le répertoire, on peut supprimer, créer ou modifier un fichier.
    Execute x 1 001 Le fichier peut être exécuté. On peut pénétrer dans ce répertoire.
    Les droits peuvent être représentés sous forme littérale (rwx, r-x, -wx, r--, ---, etc.).
    Mais aussi sous forme numérique (octale).
    Par exemple :
    • 7 correspond à rwx (7=4+2+1, ce qui correspond à 111 en binaire) ;
    • 4 correspond à r-- (7=4+0+0, ce qui correspond à 100 en binaire) ;
    • 3 correspond à -wx (3=0+2+1, ce qui correspond à 011 en binaire) ;
    • 5 correspond à r-x (5=4+0+1, ce qui correspond à 101 en binaire) ;
    • etc.
    Tout fichier appartient à un utilisateur et à un groupe. Ses droits seront de la forme rwxr-xr-x en lettres, ou 755 en octal.
  • Afficher les droits
    La commande ls -l (affichage détaillé du contenu d'un répertoire) donne les droits des fichiers de ce répertoire.
    Exemple de résultat :
        drwxr-xr-x   2 marcel marcel  4096 janv. 21  2014 bin
        drwxr-xr-x  46 marcel marcel 73728 sept. 17 15:00 Bureau
        drwxr-xr-x  12 marcel marcel  4096 janv. 17  2013 docbook
        drwxr-xr-x  47 marcel marcel  4096 sept. 24 17:55 Documents
        drwx------  11 marcel marcel  4096 oct.   1 01:09 Dropbox
        -rw-r--r--   1 marcel marcel 17850 oct.  31  2014 gnome-terminal-conf.xml
        drwxrwxr-x   6 marcel marcel  4096 août  16  2012 history-manager
        drwxr-xr-x  42 marcel marcel  4096 août  10 23:23 Images
        drwx------   8 marcel marcel  4096 juil. 12  2014 Mail
        lrwxrwxrwx   1 marcel marcel    15 août  20  2011 Musique -> /home2/Musique/
        drwxr-xr-x   2 marcel marcel  4096 oct.  27  2014 Podcasts
        drwxr-xr-x   2 marcel marcel  4096 oct.  27  2014 Public
        -rw-r--r--   1 marcel marcel   493 déc.  18  2014 terminal.conf
        drwxr-xr-x   2 marcel marcel  4096 août  10 08:19 tmp
        drwxrwxr-x   7 marcel marcel  4096 sept. 15 10:27 Vidéos
    On peut avoir les droits d'un seul fichier avec la commande ls -l nomDuFichier.
  • Modifier les droits
    • La commande chmod permet de modifier les droits sur un fichier. Seuls root et le propriétaire du fichier peuvent le faire.
      Exemples :
          chmod u+w fichier
          chmod g-r fichier
          chmod o=w fichier
          chmod u+rw,g=r,o-w fichier
          chmod 777 fichier
          chmod 740 fichier
          chmod 544 fichier
    • Les commandes chown et chgrp permettent de changer le propriétaire et le groupe d'un fichier. Seuls root et le propriétaire du fichier peuvent changer le groupe, seul root peut changer le propriétaire.
      Exemples :
      • chown marcel xxx attribue le propriétaire marcel au fichier xxx.
      • chown marcel:grp xxx attribue le propriétaire marcel et le groupe grp au fichier xxx.
      • chgrp grp xxx attribue le groupe grp au fichier xxx.
Sources et lectures intéressantes
Dernière modification : 14/10/2016

Semaine du lendi 3 octob' 2016 : TD n°4 (Cumul=6h)

Le contrôle n°1 aura lieu le mardi 18 octobre, pendant le CM n°6.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Exercice n°3

  1. Créez un répertoire droits à la racine de votre compte. Puis entrez (cd droits) dans ce répertoire.
    Toutes les questions suivantes se passeront dans ce répertoire.
    mkdir droits
    cd droits
  2. Créez un répertoire xx. Quels sont les droits qui lui sont appliqués ?
    mkdir xx
    ls -lah

    Les droits sont en principe drwxr-xr-x
  3. Créez (sans pénétrer dans le répertoire xx) un fichier vide yy dans le répertoire xx. Quels sont les droits qui lui sont appliqués ?
    touch xx/yy
    ls -lah xx
    ou ls -lah xx/yy
    Les droits sont en principe -rwxr--r--
  4. Qu'espère-t-on en écrivant « chmod -R 0 xx » ?
    On espère supprimer tous les droits sur le répertoire xx et sur tous les fichiers qu'il contient.

    Vérifiez....
    Ça ne marche pas, car une fois que les droits sont enlevés sur le répertoire, on ne peut plus accéder aux fichiers qu'il contient.
  5. Supprimez tous les droits d'accès au fichier yy.
    Il faut d'abord rétablir l'accès au répertoire xx.
    chmod u+rwx xx
    cd xx
    chmod 0 yy
    ls -lah

    Pouvez-vous maintenant supprimer le fichier ?
    Il est très probable que vous puissiez quand même le supprimer. La protection en écriture d'un fichier empêche que l'on modifie son contenu mais pas qu'on le supprime complètement. La protection en écriture d'un dossier empêche que l'on modifie son contenu c'est-à-dire que l'on y ajoute ou supprime des fichiers ou sous-dossiers. Pour empêcher la suppression du fichier « yy », il aurait fallu enlever le droit « w » sur le répertoire.
  6. À quels groupes appartenez-vous ? À quels groupes appartient votre voisin(e) ?
    Faites en sorte que votre deuxième groupe devienne le premier, puis créez un fichier vide zz.
    Que peut-on remarquer en tapant la commande « ls -lah » ?
    groups
    groups monVoisin
    newgrp unGroupe
    groups
    touch zz

    On remarque que le fichier « zz » appartient au nouveau groupe.
  7. Faites en sorte que le fichier yy (recréez-le si il a disparu) appartienne à votre troisième groupe.
    chgrp unGroupe yy
    ls -lah
  8. Faites en sorte que le fichier zz appartienne à votre voisin(e).
    chown monVoisin zz
    Mais ça ne marche pas...
Dernière modification : 17/10/2016

Semaine du lendi 10 octob' 2016 : CM n°5 (Cumul=7,5h)

Le contrôle n°1 aura lieu le mardi 18 octobre, pendant le CM n°6.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Les disques durs

(ce qui suit est fortement inspiré de https://fr.wikipedia.org/wiki/Disque_dur.)

Historique

En 1956, premier système de ce type, par IBM. La production commerciale commence en juin 1957.
Jusqu’en 1961, plus d’un millier d’unités furent vendues. Son prix : 10 000 dollars (de l’époque) par mégaoctet.
Constitué de 50 disques de 24 pouces de diamètre (environ 61 cm), deux têtes de lecture/écriture qui pouvaient se déplacer d’un plateau à un autre en moins d’une seconde. Capacité totale : 5 000 000 de caractères (5Mo).

En juin 1954, idée (IBM) de faire « voler » les têtes de lecture/écriture au-dessus de la surface des plateaux, sur un coussin d’air. Cela deviendra un produit commercial en 1961.

En 1998, IBM commercialise le premier disque dur de 25 gigaoctets, capacité présentée à l’époque par la presse comme disproportionnée par rapport aux besoins réels des particuliers.

Évolution en termes de prix ou de capacité

Entre 1980 et 2008, la surface moyenne occupée par un bit d’information sur le disque s’est vue réduite d’un facteur de plus de 100 000 (5 Mo pour un plateau en 1980 et 500 Go en 2008).

Dans le même temps, le prix du mégaoctet a été divisé par plus d'un million : le ST-506 coûtait 1 500$ en 1980, soit 300 $ par mégaoctet ; en 2008, le mégaoctet d’un disque dur ne coûtait plus qu'environ 0,00022$.

Évolution en termes de capacité de stockage

  • 1956 : 5 Mo, IBM, 24 pouces
  • 1962 : 28 Mo, IBM, 24 pouces
  • 1982 : 1,02 Go, Hitachi, 14 pouces
  • 1998 : 25 Go, IBM, 3,5 pouces17
  • 2005 : 500 Go, Hitachi, 3,5 pouces
  • 2007 : 1 To, Hitachi, 3,5 pouces
  • 2009 : 2 To, Western Digital, 3,5 pouces
  • 2010 : 3 To, Seagate, 3,5 pouces
  • 2011 : 4 To, Hitachi, 3,5 pouces
  • 2013 : 6 To, HGST21, 3,5 pouces
  • 2014 : 8 To, Seagate, 3,5 pouces

Principe de fonctionnement

Dès 1956, dans un disque dur, on trouve des plateaux rigides en rotation, d'abord en aluminium, puis en verre ou en céramique à partir de 1990. Les faces de ces plateaux sont recouvertes d’une couche magnétique, sur laquelle sont stockées les données, en binaire.

La vitesse de rotation est actuellement (2013) comprise entre 3 600 et 15 000 tours par minute.

Note : contrairement aux CD/DVD, ce sont d’abord les pistes périphériques (c'est-à-dire les plus éloignées du centre du plateau) qui sont écrites en premier (et reconnues comme « début du disque »), car c’est à cet endroit que les performances sont maximales.

Fixées au bout d’un bras, les têtes volent au-dessus de la surface du plateau sans le toucher : elles reposent sur un coussin d’air créé par la rotation des plateaux. En 1997, les têtes volaient à 25 nanomètres de la surface des plateaux ; en 2006, cette valeur est d’environ 10 nanomètres.

À l’arrêt, les têtes doivent être parquées, soit sur une zone spéciale (la plus proche du centre, il n’y a alors pas de données à cet endroit), soit en dehors des plateaux.

Si une ou plusieurs têtes entrent en contact avec la surface des plateaux, cela s’appelle un atterrissage et provoque le plus souvent la destruction des informations situées à cet endroit.
Une imperfection sur la surface telle qu’une poussière aura le même effet.

Atterrissage
Disque ayant subi un « atterrissage »
(source : http://tpe.kyvandoan.free.fr/?page_id=24)

Vous pourrez voir fonctionner un disque dur ouvert sur cette page : autopsie d'un disque dur [http://www.kevinsubileau.fr/informatique/autopsie-disque-dur.html].

Quelques photos d'une tête de lecture : http://www.sterpin.net/espacetetedisquedur.htm.

Pour bien comprendre l'échelle :

  • Les têtes de lectures volent à 30 m/s, à une hauteur de quelques nanomètres (1nm=10-9m). Une comparaison classique : cela équivaudrait pour un Boeing 747 à voler à 8mm du sol...
  • L'altitude de vol de la tête de lecture est 10 000 fois plus petite que le diamètre d'un cheveu humain.
  • La moindre poussière est 20 à 60 fois plus grosse que l'espace entre la tête et le disque. Un disque ouvert peut être considéré comme inutilisable.
  • Même une particule de fumée de cigarette, ou une empreinte digitale, sont trois fois plus grosses que l'altitude de vol...

Géométrie

Chaque plateau (possédant le plus souvent 2 surfaces utilisables) est composé de pistes concentriques séparées les unes des autres par une zone appelée « espace interpiste ». Les pistes situées à une même distance de l’axe de rotation forment un cylindre. La piste est divisée en secteurs (aussi appelés blocs) contenant les données.

Il faut donc trois coordonnées pour accéder à un bloc (ou secteur) de disque :

  1. le numéro de la piste (détermine la position du bras portant l’ensemble des têtes) ;
  2. le numéro de la tête de lecture (choix de la surface) ;
  3. le numéro du bloc (ou secteur) sur cette piste (détermine à partir de quel endroit il faut commencer à lire les données).

Puisque les pistes sont circulaires, les pistes extérieures ont une plus grande longueur que les pistes intérieures. Le fait que la vitesse de rotation des disques soit constante quelle que soit la piste lue/écrite par la tête est donc problématique. Sur les premiers disques durs, le nombre de secteurs par piste était indépendant du numéro de piste (donc les informations étaient stockées avec une densité spatiale variable selon la piste). Depuis les années 1990 et la généralisation du zone bit recording, la densité d’enregistrement est devenue constante, avec une variation du nombre de secteurs selon la piste.

Les ambitions à long terme pour la technologie des têtes de lecture visent à manipuler le spin à l’échelle de chaque électron. Les perspectives de miniaturisation, tout comme de vitesse d’exécution de tels dispositifs dépasseraient alors tout ce que la microélectronique nous laissait entrevoir jusque là.

I-nodes

(ce qui suit est fortement inspiré de https://fr.wikipedia.org/wiki/N%C5%93ud_d'index.)

C'est quoi ?

Un nœud d'index ou inode (contraction de l'anglais index et node) est une structure de données contenant des informations à propos d'un fichier stocké dans certains systèmes de fichiers (notamment de type Linux/Unix). À chaque fichier correspond un numéro d'inode (i-number) dans le système de fichiers dans lequel il réside, unique au périphérique sur lequel il est situé. Les inodes peuvent, selon le système de fichiers, contenir aussi des informations concernant le fichier, tel que son créateur (ou propriétaire), son type d'accès (par exemple sous Unix : lecture, écriture et exécution), etc.

Le numéro d'inode est un entier unique pour le système de fichier dans lequel il est stocké. Le numéro d'inode d'un fichier abcd peut être affiché avec la commande : ls -i abcd

Exemple d'utilisation : le format ext2

Ext2 est un système de fichiers courant sous Linux, bien que maintenant souvent remplacé par Ext4.

Chaque inode contient environ 64 champs, dont 13 d'entre eux contiennent des blocs pouvant être de deux types :

  • Des blocs d'adresses, qui contiennent des pointeurs vers d'autres blocs ;
  • Des blocs de données, qui contiennent les données du fichier.

Les 10 premiers champs (sur les 13) contiennent les adresses des 10 premiers blocs de données du fichier (à raison d'une adresse par bloc). Si les blocs sur lesquels pointent les 10 premiers champs sont suffisants pour contenir le fichier, les champs 11, 12 et 13 ne sont pas utilisés.

Dans le cas contraire, en plus des 10 premiers blocs, les blocs 11, 12 et 13 sont utilisés. Ces blocs fonctionnent selon un système d'indirection.
Il existe trois niveaux d'indirection :

  • La simple indirection, utilisée par le champ 11 ;
  • La double indirection, utilisée par le champ 12 ;
  • La triple indirection, utilisée par le champ 13.

Plus le niveau d'indirection est élevé, plus le nombre final de blocs de données sur lequel pointe le champ (11, 12 ou 13) sera élevé. Ce système permet donc aux fichiers d'avoir une taille considérable.

De manière concrète, chacun de ces trois champs pointe vers un bloc d'adresses, qui pourra pointer vers un ou plusieurs blocs d'adresses ou de données. En supposant que les blocs ont comme taille 1024 octets (1 Kio), et que chaque adresse (dans le cas d'un bloc d'adresses) est stockée sur 32 bits (4 octets), chaque bloc d'adresses en contiendra 256. Avec ces informations en main, il est possible de calculer la taille maximale d'un fichier :

  • Pour être stocké sur disque, un gros fichier ne pouvant pas être contenu dans 10 blocs de données devra utiliser les champs 11, 12 et 13.
  • Le champ 11 pointe vers un bloc d'adresses. Ce bloc d'adresses contient des pointeurs vers des blocs de données (256 pointeurs). C'est la simple indirection Si cela est suffisant pour contenir le fichier, en comptant les blocs pointés par les 10 premiers champs, les champs 12 et 13 ne sont pas utilisés.
  • Sinon, le système fera appel à double indirection (bloc 12). Ce bloc pointe, comme le champ 11, vers un bloc d'adresses. Or, ce bloc d'adresses ne pointe pas vers 256 blocs de données ; il pointe vers 256 autres blocs d'adresses. Ce sont ces 256 blocs d'adresses qui pointeront vers 256 blocs de données. Si ces blocs de données ne sont pas suffisants pour contenir le fichier dans son intégralité, il faut utiliser le 13e champ.
  • Le 13e champ en est un à triple indirection. Cela signifie que le champ lui-même pointe vers un bloc de 256 adresses (comme pour les blocs 11 et 12). Ces 256 pointeurs pointent chacun sur un bloc de 256 adresses, comme le champ 12. Or, ces nouveaux blocs d'adresses pointent non pas sur des blocs de données, mais sur d'autres blocs d'adresses (encore 256), qui eux, pointent vers 256 blocs de données.
  • En utilisant les suppositions définies plus haut concernant la taille d'un bloc et d'une adresse, il est alors simple de calculer la taille maximale d'un fichier dans un système de fichiers EXT2.
    Il faut d'abord déterminer sur combien de blocs de données au total le système d'indirections pointera :
    • Les 10 premiers champs pointent chacun sur 1 bloc de données ;
    • Le champ 11 (simple indirection) pointe vers 2561 blocs de données ;
    • Le champ 12 (double indirection) pointe vers 2562 blocs de données ;
    • Le champ 13 (triple indirection) pointe vers 2563 blocs de données.
    La taille maximale d'un fichier peut alors être calculée en multipliant par 1 024 octets le nombre de blocs de données total :
    1024×(10+2561+2562+2563) = 17 247 250 432.
    La taille maximale d'un fichier avec le système de fichiers EXT2 (en considérant les suppositions ci-dessus quant à la taille des blocs) est de 17 247 250 432 octets, soit environ 16 Gio (ou 17 Go).

Système de fichiers

(ce qui suit est fortement inspiré de http://doc.ubuntu-fr.org/systeme_de_fichiers.)

Qu'est-ce qu'un système de fichiers ?

Il y a tellement de données sur un disque dur qu'il doit obligatoirement y avoir un moyen de les organiser. Les systèmes de fichiers organisent les fichiers de votre ordinateur sur votre disque dur de façon à pouvoir les retrouver lorsque vous en aurez besoin.

FAT32 et le NTFS, qui sont les deux seuls systèmes de fichiers que Windows peut nativement lire. Mais il existe de nombreux autres systèmes de fichiers : ext2, ext3, ReiserFS, JFS, XFS, etc.

Les qualifications d'un système de fichiers

  • La taille maximale d'un fichier

    Si vous possédez un fichier de 100 mégaoctets et que vous tentez de l'enregistrer sur un système de fichiers n'acceptant pas les fichiers plus grands que 90 mégaoctets, l'opération d'enregistrement ne pourra pas être complétée et vous disposerez d'un fichier corrompu, incomplet.

  • La taille maximale d'une partition

    De nombreuses caractéristiques causent des limitations plus ou moins grandes quant à la taille d'une partition formatée dans un système de fichiers donné. (Voir http://doc.ubuntu-fr.org/systeme_de_fichiers#comparaison_de_systemes_de_fichiers.)

  • La gestion des droits d'accès aux fichiers et répertoires

    Ce critère définit s'il est possible ou non d'attribuer la possession d'un fichier ou d'un répertoire à un utilisateur et à un groupe d'utilisateurs, de même que de définir quelles actions les utilisateurs ont le droit d'effectuer sur les fichiers et répertoires, selon qu'ils sont propriétaires du fichier, membre du groupe propriétaire du fichier ou ni l'un ni l'autre. La possession et la gestion des droits d'accès associés s'effectue individuellement avec chaque fichier et répertoire.

    Les droits d'accès que l'on trouve habituellement sont la lecture du fichier ou répertoire, l'écriture dans celui-ci et son exécution.

  • La journalisation

    Que se produit-il si l'écriture de la chaîne est interrompue avant son terme (ce qui se produit, par exemple, lors d'une coupure de courant) fichier devient « corrompu », incomplet.

    Un système de fichiers journalisé travaille de façon à prévenir une telle corruption : lors de la sauvegarde d'un fichier, au lieu d'écrire immédiatement sur le disque dur les données à l'endroit exact où elles devraient être enregistrées, le système de fichiers écrit les données dans une autre partie du disque dur et note les changements nécessaire dans un journal, et ensuite, en arrière-plan, il repasse chacune des entrées du journal et termine le travail commencé ; lorsque la tâche est accomplie, il raye la tâche de la liste.

    L'utilisation d'un journal requiert des capacités de stockage importantes sur vos périphériques ; ces systèmes de fichiers ne sont donc pas adaptés aux médias de faible capacité, telles les cartes mémoires et les disquettes.

Comparaison de systèmes de fichiers

Voir http://doc.ubuntu-fr.org/systeme_de_fichiers#comparaison_de_systemes_de_fichiers.
Nom du système de fichiers Taille maximale d'un fichier Taille maximale d'une partition Journalisée ou non ? Gestion des droits d'accès? Notes
ext2fs
(Extended File System)
2 TiB 4 TiB Non Oui Extended File System est le système de fichiers natif de Linux. En ses versions 1 et 2, on peut le considérer comme désuet, car il ne dispose pas de la journalisation. Ext2 peut tout de même s'avérer utile sur des disquettes 3½ et sur les autres périphériques dont l'espace de stockage est restreint, car aucun espace ne doit être réservé à un journal.
ext3fs 2 TiB 4 TiB Oui Oui ext3 est essentiellement ext2 avec la gestion de la journalisation. Il est possible de passer une partition formatée en ext2 vers le système de fichiers ext3 (et vice versa) sans formatage.
ext4fs 16 TiB 1 EiB Oui Oui ext4 est le successeur du système de fichiers ext3. Il est cependant considéré par ses propres concepteurs comme une solution intermédiaire en attendant le vrai système de nouvelle génération que sera Btrfs
ReiserFS 8 TiB 16 TiB Oui Oui Développé par Hans Reiser et la société Namesys, ReiserFS est reconnu particulièrement pour bien gérer les fichiers de moins de 4 ko. Un avantage du ReiserFS, par rapport à ext3, est qu'il ne nécessite pas une hiérarchisation aussi poussée: il s'avère intéressant pour le stockage de plusieurs fichiers temporaires provenant d'Internet. Par contre, ReiserFS n'est pas recommandé pour les ordinateurs portables, car le disque dur tourne en permanence, ce qui consomme beaucoup d'énergie.
FAT
(File Allocation Table)
2 GiB 2 GiB Non Non* Développé par Microsoft, ce système de fichiers se rencontre moins fréquemment aujourd'hui. Il reste néanmoins utilisé sur les disquettes 3½ formatées sous Windows et devrait être utilisé sous Linux si une disquette doit aussi être lue sous Windows. Il est aussi utilisé par plusieurs constructeurs comme système de fichiers pour cartes mémoires (memory sticks), car, bien documenté, ce système de fichiers reste le plus universellement utilisé et accessible.
FAT32 4 GiB 8 TiB Non Non* Ce système de fichiers, aussi créé par Microsoft, est une évolution de son prédécesseur. Depuis ses versions 2000 SP4 et XP, Windows ne peut pas formater (ou bloque volontairement le formatage) une partition en FAT32 d'une taille supérieure à 32 Go. Cette limitation ne s'applique pas sous Linux, de même qu'avec des versions antérieures de Windows. Une partition FAT32 d'une taille supérieure à 32 Go déjà formatée pourra être lue par Windows, peu importe sa version.
NTFS
(New Technology File System)
16 TiB 256 TiB Oui Oui* Ce système de fichiers a aussi été développé par Microsoft, et il reste très peu documenté. L'écriture depuis Linux sur ce système de fichiers est stable à l'aide du pilote ntfs-3g. Ce pilote est inclus de base depuis Ubuntu 7.10, et disponible en paquets dans les dépôts pour les versions antérieures.
EiB = Exbioctets (1024 pébioctets) :: PiB = Pébioctet (1024 tébioctet) :: TiB = Tébioctet (1024 gibioctets) :: GiB = Gibioctet (1024 mibioctets)

Linux et les systèmes de fichiers de Microsoft

Parmi les systèmes de fichiers précédents, les seuls sur lesquels on ne peut pas installer Linux sont le NTFS, la FAT et la FAT32. En théorie, il pourrait être possible d'installer Linux sur l'un de ces systèmes de fichiers, mais comme ce système de fichiers ne gère pas les droits d'accès, il résulterait un système d'exploitation hautement non-sécurisé.

Sous Windows, le système de fichiers NTFS gère les droits d'accès basé sur une liste de contrôle (ACL) qui n'est pas prise en compte sous Linux. Linux peut aussi prendre en charge une forme d'ACL, mais celle-ci est différente de celle implantée dans NTFS. Pour cette raison, les ACL des systèmes de fichiers NTFS sont simplement ignorées.

Petite parenthèse : la (dé-)fragmentation des fichiers...

Texte trouvé sur http://forum.ubuntu-fr.org/viewtopic.php?id=193846.

Imaginez que votre disque dur soit une énorme armoire à fichiers, avec des millions de tiroirs. Chaque tiroir peut contenir une quantité donnée d'informations, de sorte que les fichiers trop gros pour tenir dans un tiroir doivent être répartis dans plusieurs tiroirs. Certains fichiers sont si gros qu'ils occupent plusieurs milliers de tiroirs. Et bien sûr, l’accès à ces fichiers est beaucoup plus facile lorsque tous les tiroirs qu'ils occupent sont proches les uns des autres dans l’armoire.

Imaginez maintenant que vous soyez l'heureux possesseur de cette armoire à fichiers, mais que vous n'ayez pas le temps de vous occuper de son classement : vous voulez embaucher quelqu’un pour le faire à votre place. Deux personnes se présentent pour le poste, un homme et une femme.

L'homme a la stratégie suivante : il vide simplement les tiroirs quand un fichier est effacé, découpe les nouveaux fichiers en morceaux de la taille d'un tiroir, et place chaque morceau aléatoirement dans le premier tiroir libre. Lorsque vous évoquez le fait qu'il risque d'être difficile de retrouver tous les morceaux d’un fichier donné, l'homme répond qu'il faut embaucher une douzaine de gars costauds tous les week-ends pour remettre l’armoire en ordre.

La femme a une technique différente : elle tient à jour, sur une feuille de papier, la liste de tous les tiroirs vides contigus. Lorsqu'arrive un nouveau fichier, elle cherche dans la liste une suite de tiroirs contigus suffisamment longue pour contenir le fichier, et c’est là qu’elle le place. De cette façon, pourvu qu’il y ait suffisamment d’activité, l’armoire reste toujours rangée. Sans aucun doute, vous devriez embaucher la femme.

Windows utilise la première méthode et GNU/Linux, la seconde. Plus vous utilisez Windows, plus l’accès aux fichiers est lent ; plus vous utilisez GNU/Linux, plus il est rapide.

Représentation pour l'utilisateur

Pour l'utilisateur, un système de fichiers est vu comme une arborescence : les fichiers sont regroupés dans des répertoires (concept utilisé par la plupart des systèmes d’exploitation). Ces répertoires contiennent soit des fichiers, soit récursivement d'autres répertoires. Il y a donc un répertoire racine et des sous-répertoires. Une telle organisation génère une hiérarchie de répertoires et de fichiers organisés en arbre.

Différentes méthodes permettent d'associer un nom de fichier à son contenu. Dans le cas du système de fichiers FAT, ancien système de fichiers de MS-DOS et de Windows encore largement utilisé sur les supports amovibles comme les clés USB, chaque répertoire contient une table associant les noms de fichiers à leur taille et un index pointant vers la table d'allocation de fichiers, une zone réservée du disque indiquant pour chaque bloc de données l'index du bloc suivant du même fichier.

Dans le cas des systèmes de fichier d'Unix (ou de Linux/Minix), les fichiers et les répertoires sont identifiés par un numéro unique, le numéro d'inode. Ce numéro permet d'accéder à une structure de données (inode) regroupant toutes les informations sur un fichier à l'exception du nom, notamment la protection d'accès en lecture, en écriture ou des listes de dates, ainsi que le moyen d'en retrouver le contenu. Le nom est stocké dans le répertoire associé à un numéro d'inode. Cette organisation présente l'avantage qu'un fichier unique sur disque peut être connu du système sous plusieurs noms.

Lectures intéressantes pour aller plus loin...

Mémoires SSD / SSD vs HD

Informations de base

  • SSD = solid-state drive
    Même technologie que les clefs USB et les cartes SD.
  • Avantages : meilleures performances (débit plus important, latence inexistante), faible consommation électrique, faible encombrement, pas d'usure mécanique (aucune pièce mobile), résistance aux chocs et aux vibrations, silence total.
  • Inconvénients : nombre d'écritures limité sur chaque zone, capacité limitée.
  • Ne jamais défragmenter : pas d'utilité, et ça raccourcit la durée de vie.
  • Éviter une occupation trop importante (ne pas dépasser 60%)
  • En résumé, pour qu'un SSD vive longtemps... il ne faut pas l'utiliser : il faut lui éviter au maximum les écritures inutiles qui usent les puces mémoires. Utiliser pour le système plutôt que pour les données.

Lectures pour aller plus loin...

Dernière modification : 29/10/2016

Semaine du lendi 10 octob' 2016 : TD n°5 (Cumul=7,5h)

Le contrôle n°1 aura lieu le mardi 18 octobre, pendant le CM n°6.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Retour sur les disques durs...

Les commandes linux, suite

  • Trouver l'adresse IP de sa propre machine : ifconfig (ou /sbin/ifconfig) sous linux ou ipconfig sous windows.

Faire communiquer des programmes par le réseau

Une série de petits exemples en Python pour comprendre comment des programmes peuvent communiquer.
  • Première version simpliste : une connexion
    1. ##############################################################
    2. #
    3. # Démonstration de connexion - SERVEUR
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # création d'une socket avec adresses Internet et protocole TCP
    12. connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    13.  
    14. # associer le port 12800 pour écouter (on peut prendre n'importe
    15. # lequel, mais le client devra se connecter par le même port)
    16. connexion_principale.bind(('', 12800))
    17.  
    18. # lancer l'écoute (on traite au maximum 5 demandes en même temps, mais
    19. # on peut avoir beaucoup plus de connexions actives en même temps)
    20. connexion_principale.listen(5)
    21.  
    22. # accept bloque le programme en attendant une demande de connexion
    23. # d'un client
    24. connexion_avec_client, infos_connexion = connexion_principale.accept()
    25.  
    26. # quand le programme se débloque (une connnexion a été demandée),
    27. # afficher les infos de connexion
    28. print(infos_connexion)
    29.  
    et
    1. ##############################################################
    2. #
    3. # Démonstration de connexion - CLIENT
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # création d'une socket avec adresses Internet et protocole TCP
    12. connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    13.  
    14. # tentative de connexion sur le port 12800 du serveur, sur la machine
    15. # locale (si le serveur est sur une autre machine, mettre l'adresse IP
    16. # ou l'adresse domainisée de la machine cible)
    17. connexion_avec_serveur.connect(('localhost', 12800))
    18.  
  • Deuxième version  : début de communication
    1. ##############################################################
    2. #
    3. # Démonstration de communication - SERVEUR
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # création d'une socket avec adresses Internet et protocole TCP
    12. connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    13.  
    14. # associer le port 12800 pour écouter (on peut prendre n'importe
    15. # lequel, mais le client devra se connecter par le même port)
    16. connexion_principale.bind(('', 12800))
    17.  
    18. # lancer l'écoute (on traite au maximum 5 demandes en même temps, mais
    19. # on peut avoir beaucoup plus de connexions actives en même temps)
    20. print("Serveur en attente de connexion...")
    21. connexion_principale.listen(5)
    22.  
    23. # accept bloque le programme en attendant une demande de connexion
    24. # d'un client
    25. connexion_avec_client, infos_connexion = connexion_principale.accept()
    26.  
    27. # quand le programme se débloque (une connexion a été demandée),
    28. # afficher les infos de connexion
    29. print("Connexion acceptée depuis l'IP", infos_connexion[0], "sur le port",infos_connexion[1])
    30.  
    31. # envoi d'un message vers le client, la valeur en retour est le nombre
    32. # d'octets envoyés
    33. nbre = connexion_avec_client.send(b"Je viens d'accepter la connexion.")
    34. print(nbre,'octets envoyés')
    35.  
    36. # fermer la connexion
    37. connexion_avec_client.close()
    38. connexion_principale.close()
    39. print("Connexion fermée")
    40.  
    et
    1. ##############################################################
    2. #
    3. # Démonstration de communication - CLIENT
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # création d'une socket avec adresses Internet et protocole TCP
    12. connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    13.  
    14. # tentative de connexion sur le port 12800 du serveur, sur la machine
    15. # locale (si le serveur est sur une autre machine, mettre l'adresse IP
    16. # ou l'adresse domainisée de la machine cible)
    17. print("Tentative de connexion au serveur...")
    18. connexion_avec_serveur.connect(('localhost', 12800))
    19. print("Connexion au serveur réussie.")
    20.  
    21. # Attente d'un éventuel message venant du serveur, et affichagedu message
    22. msg_recu = connexion_avec_serveur.recv(1024)
    23. print ("Message reçu: ", msg_recu)
    24.  
    25. # fermer la connexion
    26. connexion_avec_serveur.close()
    27. print("Connexion fermée")
    28.  
  • Troisième version  : vraie communication
    1. ##############################################################
    2. #
    3. # Démonstration de communication - SERVEUR amélioré
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # paramètres de la connexion côté serveur
    12. hote = ''
    13. port = 12800
    14.  
    15. # création d'une socket avec adresses Internet et protocole TCP
    16. connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    17.  
    18. # associer le port pour écouter
    19. connexion_principale.bind((hote, port))
    20.  
    21. # lancer l'écoute (on traite au maximum 5 demandes en même temps, mais
    22. # on peut avoir beaucoup plus de connexions actives en même temps)
    23. connexion_principale.listen(5)
    24. print("Le serveur écoute à présent sur le port {}".format(port))
    25.  
    26. # attente bloquante d'une demande de connexion
    27. connexion_avec_client, infos_connexion = connexion_principale.accept()
    28.  
    29. # quand le programme se débloque (une connexion a été demandée),
    30. # afficher les infos de connexion
    31. print("Connexion acceptée depuis l'IP", infos_connexion[0], "sur le port",infos_connexion[1])
    32.  
    33. # boucler tant qu'on qu'on ne reçoit pas le message "fin" qui fermera
    34. # la connexion
    35. msg_recu = b""
    36. while msg_recu != b"fin":
    37.     msg_recu = connexion_avec_client.recv(1024)
    38.     # (L'instruction ci-dessous peut lever une exception si le message
    39.     # Réceptionné comporte des accents)
    40.     # affichage du message reçu et envoi de la confirmation
    41.     print(msg_recu.decode())
    42.     connexion_avec_client.send(b"5 / 5")
    43.  
    44. # fermer la connexion
    45. print("Fermeture de la connexion")
    46. connexion_avec_client.close()
    47. connexion_principale.close()
    48.  
    et
    1. ##############################################################
    2. #
    3. # Démonstration de communication - CLIENT amélioré
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. # pour les  connexions par socket
    9. import socket
    10.  
    11. # paramètres de la connexion côté serveur
    12. hote = "172.30.110.11"
    13. port = 12800
    14.  
    15. # création d'une socket avec adresses Internet et protocole TCP
    16. connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    17.  
    18. # tentative de connexion sur le serveur
    19. connexion_avec_serveur.connect((hote, port))
    20. print("Connexion établie avec le serveur sur le port {}".format(port))
    21.  
    22. # boucler tant qu'on qu'on n'envoie pas le message "fin" qui fermera
    23. # la connexion
    24. msg_a_envoyer = b""
    25. while msg_a_envoyer != b"fin":
    26.     msg_a_envoyer = input("> ")
    27.     # Peut planter si vous tapez des caractères spéciaux
    28.     msg_a_envoyer = msg_a_envoyer.encode()
    29.     # On envoie le message
    30.     connexion_avec_serveur.send(msg_a_envoyer)
    31.     # réception de la réponse du serveur
    32.     msg_recu = connexion_avec_serveur.recv(1024)
    33.     print(msg_recu.decode()) # Là encore, peut planter s'il y a des accents
    34.  
    35. print("Fermeture de la connexion")
    36. connexion_avec_serveur.close()
    37. print("Connexion fermée")
    38.  
  • Version évoluée : communication simultanée avec plusieurs clients
    1. ##############################################################
    2. #
    3. # Démonstration de communication - SERVEUR évolué (fonctionne avec CLIENT amélioré)
    4. #
    5. # source: http://openclassrooms.com/courses/apprenez-a-programmer-en-python/le-reseau
    6. ##############################################################
    7.  
    8. import socket
    9. import select
    10.  
    11. hote = ''
    12. port = 12800
    13.  
    14. connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    15. connexion_principale.bind((hote, port))
    16. connexion_principale.listen(5)
    17. print("Le serveur écoute à présent sur le port {}".format(port))
    18.  
    19. serveur_lance = True
    20. clients_connectes = []
    21. adresses={}
    22. while serveur_lance:
    23.     # On va vérifier que de nouveaux clients ne demandent pas à se connecter
    24.     # Pour cela, on écoute la connexion_principale en lecture
    25.     # On attend maximum 50ms
    26.     connexions_demandees, wlist, xlist = select.select([connexion_principale],
    27.         [], [], 0.05)
    28.    
    29.     for connexion in connexions_demandees:
    30.         connexion_avec_client, infos_connexion = connexion.accept()
    31.         # On ajoute le socket connecté à la liste des clients
    32.         clients_connectes.append(connexion_avec_client)
    33.         adresses[connexion_avec_client]=infos_connexion[0]+":"+str(infos_connexion[1])
    34.         print(adresses[connexion_avec_client],"vient de se connecter\n")
    35.     # Maintenant, on écoute la liste des clients connectés
    36.     # Les clients renvoyés par select sont ceux devant être lus (recv)
    37.     # On attend là encore 50ms maximum
    38.     # On enferme l'appel à select.select dans un bloc try
    39.     # En effet, si la liste de clients connectés est vide, une exception
    40.     # Peut être levée
    41.     clients_a_lire = []
    42.     try:
    43.         clients_a_lire, wlist, xlist = select.select(clients_connectes,
    44.                 [], [], 0.05)
    45.     except select.error:
    46.         pass
    47.     else:
    48.         # On parcourt la liste des clients à lire
    49.         for client in clients_a_lire:
    50.             # Client est de type socket
    51.             msg_recu = client.recv(1024)
    52.             # Peut planter si le message contient des caractères spéciaux
    53.             msg_recu = msg_recu.decode()
    54.             print("Reçu de",adresses[client],": {}".format(msg_recu))
    55.             client.send(b"5 / 5")
    56.             if msg_recu == "fin":
    57.                 serveur_lance = False
    58.  
    59. print("Fermeture des connexions")
    60. for client in clients_connectes:
    61.     client.close()
    62.  
    63. connexion_principale.close()
    64.  
    On peut utiliser le client précédent (n°3).
Dernière modification : 17/10/2016

Semaine du lendi 17 octob' 2016 : CM n°6 (Cumul=9h)

Contrôle n°1 (vous pouvez consulter la correction du contrôle).
Dernière modification : 21/10/2016

Semaine du lendi 17 octob' 2016 : TD n°6 (Cumul=9h)

Le contrôle n°2 aura lieu le vendredi 11 novembre, de 15h00 à 17h00, en salle C.11.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Comment réviser si je n'ai pas linux chez moi ?

Sous Windows vous pouvez installer CygWin [https://www.cygwin.com/].

Vous pouvez aussi utiliser un émulateur de terminal sur le web. Par exemple :

Exercice n°2, le retour

  1. Créez, dans votre répertoire personnel, un répertoire CommandesLinux contenant l'arborescence suivante :
    .
    ├── couleur
    │   └── froide
    └── forme
        ├── angle
        └── courbe
    cd
    mkdir CommandesLinux
    mkdir CommandesLinux/couleur
    mkdir CommandesLinux/couleur/froide
    mkdir CommandesLinux/forme
    mkdir CommandesLinux/forme/angle
    mkdir CommandesLinux/forme/courbe

    ou
    cd
    mkdir CommandesLinux CommandesLinux/couleur CommandesLinux/couleur/froide CommandesLinux/forme CommandesLinux/forme/angle CommandesLinux/forme/courbe

    ou
    cd
    mkdir CommandesLinux
    cd CommandesLinux
    mkdir couleur
    mkdir forme
    cd couleur
    mkdir froide
    cd ../forme
    mkdir angle
    mkdir courbe
  2. Copiez le fichier /etc/services dans votre répertoire CommandesLinux.
    En étant dans le répertoire CommandesLinux :
      cp -R /etc/services .
  3. À qui (et à quel groupe) appartient le fichier que vous venez de copier ? Quelle est sa date de sa dernière modification ?
    Il vous appartient, et sa date de modification est l'heure de la copie.
    Ces informations sont accessibles par la commande ls -lah
  4. Créez dans le répertoire CommandesLinux les fichiers ne contenant aucune donnée et dont les noms sont : rond.txt, triangle.txt, carre.txt, rectangle.txt, vert.txt et bleu.txt.
    touch rond.txt triangle.txt carre.txt rectangle.txt vert.txt bleu.txt
  5. Déplacez le fichier rond.txt dans le répertoire courbe et les fichiers triangle.txt, carré.txt, rectangle.txt dans le répertoire angle.
    mv rond.txt forme/courbe
    mv triangle.txt carre.txt rectangle.txt forme/angle
  6. Déplacez les fichiers vert.txt et bleu.txt dans le répertoire froide.
    mv vert.txt bleu.txt couleur/froide
  7. Allez dans le répertoire couleur et afficher le contenu du répertoire de façon récursive.
    cd couleur
    ls -R
  8. Copier le répertoire froide sous le nom chaude.
    cp -R froide chaude
  9. Allez dans le répertoire chaude et renommez le fichier bleu.txt en rouge.txt, et vert.txt en jaune.txt.
    cd chaude
    mv bleu.txt rouge.txt
    mv vert.txt jaune.txt
  10. Remontez dans le répertoire CommandesLinux et renommez le répertoire couleur en peinture.
    cd ../..
    mv couleur peinture
  11. Affichez le contenu du fichier /etc/issue. Que contient-il ?
    cat /etc/issue
    Il contient le message affiché lors d'une connexion sur un terminal.
  12. Affichez page par page le contenu du fichier /etc/services. Que contient-il ?
    more /etc/services ou less /etc/services
    Il fournit une correspondance entre un nom intelligible décrivant un service Internet et l'ensemble numéro de port/protocole utilisé.
    Chaque programme réseau devrait consulter ce fichier pour obtenir le numéro de port et le protocole sous-jacent au service qu'il fournit.

Les commandes linux, suite

Dernière modification : 15/11/2016

Semaine du lendi 24 octob' 2016 : CM n°7 (Cumul=10,5h)

Le contrôle n°2 aura lieu le vendredi 18 novembre, de 15h00 à 17h00, en salle C.11.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Cyberattaque

« Cyberattaque géante aux États-Unis : ce que l'on sait », un article de Libération en date du 22 octobre 2016.

Machine virtuelle

(Source : Machine virtuelle sur Wikipedia [https://fr.wikipedia.org/wiki/Machine_virtuelle] )

Une machine virtuelle est une illusion d'un appareil informatique créée par un logiciel d'émulation. Le logiciel d'émulation simule la présence de ressources matérielles et logicielles telles que la mémoire, le processeur, le disque dur, voire le système d'exploitation et les pilotes, permettant d'exécuter des programmes dans les mêmes conditions que celles de la machine simulée.

Un des intérêts des machines virtuelles est de pouvoir s'abstraire des caractéristiques de la machine physique utilisée (matérielles et logicielles — notamment système d'exploitation), permettant une forte portabilité des logiciels et la gestion de systèmes hérités étant parfois conçus pour des machines ou des environnements logiciels anciens et plus disponibles.

Les machines virtuelles sont également utilisées pour isoler des applications pour des raisons de sécurité, pour augmenter la robustesse d'un serveur en limitant l'impact des erreurs système ou pour émuler plusieurs machines sur une seule machine physique (virtualisation).

L'inconvénient des machines virtuelles est généralement des performances brutes inférieures à l'exécution dans l'environnement natif.

L'usage de machines virtuelles est l'un des principes fondamentaux de la technologie Java.

Comment réviser si je n'ai pas linux chez moi, le retour...

Utilisation dans une machine virtuelle

Vous pouvez utiliser une machine virtuelle installée sous Windows. Il s'agit d'un programme qui simule le fonctionnement d'un ordinateur.
Vous trouverez des renseignements dans cet article d'openclassroom : Installez Linux dans une machine virtuelle.

Wubi

Wubi est un installateur officiel d'Ubuntu qui va vous permettre d'installer Ubuntu, directement à partir de Windows, de la même façon que vous installeriez n'importe quel logiciel. Ici, pas besoin de créer des partitions, un disque dur virtuel prenant la forme d'un simple fichier est utilisé.
Vous trouverez des renseignements dans cet article de pcastuces : Installer et désinstaller Linux Ubuntu avec Windows.

Retour sur la communication entre programmes

Connexion

Il y a d'autres façons de connecter deux machines, mais en TD on a choisi d'utiliser le protocole d'internet, TCP/IP.

Les machines sont alors identifiées par leur adresse IP [https://fr.wikipedia.org/wiki/Adresse_IP].

Raisons du développement d'un nouveau protocole IP

(Source : IPv6 sur Wikipedia [https://fr.wikipedia.org/wiki/IPv6] )

Le protocole IPv4 permet d'utiliser un peu plus de quatre milliards d'adresses différentes pour connecter les ordinateurs et les autres appareils reliés au réseau. Au début d'Internet, dans les années 1970, il était pratiquement inimaginable qu'il y aurait un jour suffisamment de machines sur un unique réseau pour que l'on commence à manquer d'adresses disponibles.

Une partie des quatre milliards d'adresses IP théoriquement disponibles ne sont pas utilisables pour numéroter des machines, entre autres parce qu'elles sont destinées à des usages particuliers.

Le nombre d'adresses IP Version 4 publiques est arrivé officiellement à saturation le 3 février 2011.

Pour IPv6 on utilise 16 octets (c'est-à-dire 128 bits, soit environ 3,4×1038 adresses disponibles) au lieu de 4 octets pour IPv4 (32 bits, soit environ 4,3×109 adresses disponibles). Pour épuiser la totalité de ce stock d'adresses, il faudrait placer 667 millions de milliards d'appareils connectés sur chaque millimètre carré de la surface de la Terre

Remarque  Les nombres exacts d'adresses possibles sont 4 294 967 296 pour IPv4, et 340 282 366 920 938 463 463 374 607 431 768 211 456 pour IPv6...

Alors qu'une adresse IPv4 est représentée par 4 nombres décimaux séparés par des points (par exemple 172.31.128.1), une adresse IPv6 est représentée par 8 groupes de deux octets en notation héxadécimale séparés par un signe deux-points (par exemple 2001:0db8:0000:85a3:0000:0000:ac1f:8001).

Connexion locale

Vous pouvez toujours contacter la machine sur laquelle vous êtes, comme vous le feriez pour une machine distante, en utilisant le nom localhost [https://fr.wikipedia.org/wiki/Localhost] qui correspond le plus souvent à l'adresse 127.0.0.1.

Répartition des communications sur le réseau

Tous les échanges entre les machines d'un même réseau se font sur un seul et même fil, un câble ethernet [https://fr.wikipedia.org/wiki/Ethernet] (ou une liaison wifi [https://fr.wikipedia.org/wiki/Wi-Fi], mais le principe est le même).
Le fait que les autres machines ne reçoivent pas les données qui vous sont destinées n'est qu'une apparence. En réalité, elles sont seulement très polies et bien élevées, et elles n'ouvrent pas le courrier qui ne leur est pas destiné : toutes les machines du réseau voient passer toutes les données de tout le monde ; ces données sont accompagnées de l'adresse IP du destinataire ; les autres machines, bien élevées, ne les lisent pas.
Mais cela n'empêcherait pas un utilisateur animé de mauvaises intentions de capturer ces données au passage et d'en faire l'usage qu'il lui plaît, et ceci sans que vous puissiez vous en rendre compte. Les logiciels qui permettent cela sont appelés renifleurs [https://fr.wikipedia.org/wiki/Analyseur_de_paquets] (sniffers en anglais). La seule parade contre ces pratiques est l'utilisation de transmissions cryptées (ssh au lieu de telnet, https au lieu de http, etc.) : ça n'empêchera pas un sniffer de les lire vos données au passage, mais il ne pourra en comprendre le contenu.

Des infos sur les sniffers :

Ports logiciels

On pourrait également s'étonner que les données provenant de plusieurs sources ne se mélangent pas en arrivant sur la machine qui les a demandées : comment l'ordinateur fait-il pour distinguer les données qui correspondent à la page web que vous êtes en train de consulter et celles qui correspondent à la musique que vous êtes en train d'écouter en streaming en même temps ?
La solution réside dans l'utilisation des ports [https://fr.wikipedia.org/wiki/Port_%28logiciel%29].
À chaque fois qu'une connexion est établie entre deux machines, c'est-à-dire en réalité entre deux programmes, chaque programme indique à l'autre quel port il associe à cette communication (chacun le sien, aucune raison pour que ce soit les mêmes). Il s'agit d'un simple nombre (compris entre 0 et 65 535, parce que codé sur 16 bits : 216=65 536).
Vous pouvez, si cela vous aide, vous représenter cela comme une porte derrière laquelle se tiendra le programme en attente de communication venant de son interlocuteur, le numéro de port étant le numéro de la porte.

L'utilisation des ports pour contourner la pénurie d'adresses IP4

Certains fournisseurs d'accès (Free par exemple) utilisent des plages de ports pour répartir une seule adresse IP sur plusieurs machines : pour une même adresse IP, on aura quatre clients, un sur les ports 0-16383, le deuxième sur 16384-32767, le troisième sur 32768-49151, et le quatrième sur 49152-65536.

Ce mécanisme est totalement transparent, et n'a aucune conséquence pour les utilisateurs, à condition de ne pas avoir installé de serveur ouvert sur internet sur votre machine. Si c'est le cas, votre serveur sera sans doute inaccessible si vous n'êtes pas celui à qui a été attribuée la plage 0-16383.
Heureusement un outil est disponible sur le site de Free pour demander l'attribution d'une adresse fixe, avec tous les ports...

Des infos supplémentaires dans ces deux articles : « Free associe une seule adresse IPv4 en ZMD à plusieurs abonnés, en partageant les ports » sur universfreebox, et « Des abonnés Free reçoivent ¼ d’adresse IP » sur linuxfr.

Client/serveur

Pour qu'une connexion se fasse, il faut deux programmes, un serveur et un client (on parle alors de modèle client/serveur [https://fr.wikipedia.org/wiki/Client-serveur]). Le serveur est un programme qui attend qu'on lui demande quelque chose. Le client est un programme qui va demander un service au serveur, et qui espère avoir une réponse en retour.

Pour que la connexion puisse se faire il faut que le serveur tourne au moment où le client va faire sa demande. Ce qui fait qu'en général, puisqu'on ne sait pas par avance quand le client va se manifester, le serveur doit tourner en permanence.
Tandis que le client ne tournera qu'au moment où on a besoin de demander quelque chose.

Le port sur lequel écoute le serveur (la porte derrière laquelle il attend) doit être connu des clients potentiels. Il ne peut pas changer sans raison. Par exemple, les serveurs web sont a priori sur le port 80.
Tandis que le client peut choisir lui-même le numéro du port sur lequel il attendra la réponse du serveur, et il va transmettre ce numéro de port au serveur, lors de la première connexion.

Exemples de fonctionnements en client/serveur :

Service concerné Serveur Client
Web Apache, IIS navigateur
Courrier SMTP, POP, IMAP Thunderbird, Outlook
Graphisme sous linux Serveur X Tous les programmes qui ont besoin de produire un affichage

Paquets

Une autre chose pourrait faire croire que ce qui se balade sur internet devrait arriver à destination dans le désordre le plus total : la technologie des paquets [https://fr.wikipedia.org/wiki/Paquet_%28r%C3%A9seau%29].

Quand des données sont transférées par internet, elles ne sont pas envoyées en un seul morceau, mais découpées en blocs, qu'on appelle des « paquets ». On sait déjà que le chemin sur internet est imprévisible, il l'est aussi entre les paquets : les différents paquets d'un même ensemble de données (une vidéo, une page web, un mail, etc.) peuvent parfaitement suivre des chemins différents. Ce n'est qu'une fois arrivés à destination que la machine de destination les rassemblera, dans l'ordre (ils sont numérotés), et reconstruira l'ensemble de données originel.

Il faut d'ailleurs remarquer que protocole d'internet est considéré comme non fiable : rien dans ses spécifications ne garantit que les données doivent arriver à destination. Heureusement, la plupart du temps ça marche...

Exécution d'un programme

Que se passe-t-il réellement lors de l'exécution d'un programme ?
Dans la machine tout est binaire. Quelle est la différence entre programme et données ?

Interprété ? Compilé ?

La seule chose que « comprend » l'ordinateur, c'est le binaire. Un programme doit donc être traduit avant d'être utilisé.

On peut le traduire une fois et conserver la traduction binaire. On dit alors que le programme a été compilé.

On peut aussi traduire le programme à la demande, à chaque fois qu'on en a besoin, au fur et à mesure de son exécution. On dit alors que le programme est interprété.

Il existe aussi une méthode hybride : le programme est traduit une seule fois, pas en binaire, mais dans un langage intermédiaire, qui sera exécuté par une machine virtuelle [https://fr.wikipedia.org/wiki/Machine_virtuelle].
L'intérêt est alors de n'avoir à compiler traduire qu'une seule fois le code source pour pouvoir l'exécuter sur différentes machines (cf. le slogan de java : « write once, run anywhere », qu'on peut traduire par « écrire une fois, utiliser n'importe où »). On dit alors que le programme est semi-interprété (ou semi-compilé).

Il est à noter qu'il est abusif de parler de « langage interprété » ou de « langage compilé ». Ce sont les programmes qui sont interprétés ou compilés. Tout langage peut être compilé, tout langage peut être interprété.
Quand on parle de « langage interprété » ou de « langage compilé », on veut dire « langage dont les programmes sont en général interprétés » ou « langage dont les programmes sont en général compilés ». Beaucoup plus simple, non ?

Exemples :

  • Compilés en général : C/C++, COBOL, Fortran, pascal.
  • Interprétés en général : Basic, C#, JavaScript, PHP, Perl, PostScript, R, SQL, shell (langage de commande linux).
  • Utilise une machine virtuelle en général : Java, Lisp, Python.

Y a-t-il une différence entre programme et données ?

Quand vous avez exécuté les programmes python d'un TD précédent, vous avez par exemple tapé la commande python3 serveur1.py.
Où est le programme là-dedans ? Où sont les données ?
Vous aviez un fichier texte nommé serveur1.py, et il a servi en tant que données d'entrée au programme python3.

Tout le monde conviendra que serveur1.py est un programme. Pourtant, dans ce cas c'était clairement une donnée.

Il est très difficile, voire même impossible, de tracer une frontière entre programmes et données. Si on creuse un peu, on finit toujours par se rendre compte qu'un programme n'est qu'un peu d'information utilisée par un programme de plus bas niveau :

  • python3 est-il lui-même un programme ? Il est en fait manipulé, exécuté, utilisé par linux.
  • linux n'est lui qu'une donnée utilisée par le processeur...
  • ... dont les registres sont eux-même manipulés par le séquenceur.
  • etc.

Lectures pour aller plus loin...

Dernière modification : 15/11/2016

Semaine du lendi 24 octob' 2016 : TD n°7 (Cumul=10,5h)

Le contrôle n°2 aura lieu le vendredi 11 novembre, de 15h00 à 17h00, en salle C.11.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Créer un fichier de commandes (=un script shell) sous linux

Créer un fichier texte contenant les commandes, le rendre exécutable (chmod +x marcel).
C'est tout....

Il est recommandé d'ajouter « #!/bin/bash » en première ligne du fichier. Cela indique quel est l'interpréteur de commandes à utiliser pour exécuter ce script (ici c'est bash).

On peut aussi écrire « sh script ».

Exercice n°4

Créer un script shell qui résolve les 10 premières questions de l'exercice du TD 6.

Enregistrez, sous n'importe quel nom (dans la suite nous supposerons qu'il s'appelle marcel), dans votre répertoire personnel un fichier texte qui contiendra :
#!/bin/bash
cd
mkdir CommandesLinux
mkdir CommandesLinux/couleur
mkdir CommandesLinux/couleur/froide
mkdir CommandesLinux/forme
mkdir CommandesLinux/forme/angle
mkdir CommandesLinux/forme/courbe
cd CommandesLinux
cp -R /etc/services .
ls -lah
touch rond.txt triangle.txt carre.txt rectangle.txt vert.txt bleu.txt
mv rond.txt forme/courbe
mv triangle.txt carre.txt rectangle.txt forme/angle
mv vert.txt bleu.txt couleur/froide
cd couleur
ls -R
cp -R froide chaude
cd chaude
mv bleu.txt rouge.txt
mv vert.txt jaune.txt
Puis donnez-lui les droits d'exécution : chmod u+x marcel
Il ne vous reste plus qu'à l'éxécuter de n'importe où : ~/marcel

Un peu plus loin dans les scripts shell

  • Paramètres : $1 $2 $3...
  • echo
  • Le chemin d'accès aux exécutables : $PATH
    (Taper « echo $ » suvi d'une tabulation pour avoir la liste de toutes les variables d'environnement...)
  • Redirection des sorties : > et >>

Exercice n°5

  • Créer un script shell qui accepte un nom de fichier en paramètre, affiche les droits qui lui sont appliqués (ls -l), supprime tous les droits du groupe et du reste du monde sur ce fichier, puis affiche les droits à nouveau.
    #!/bin/bash
    echo Droits de $1 AVANT modification
    ls -lah $1
    echo
    echo Changement des droits en cours....
    chmod go-rwx $1
    echo
    echo Droits de $1 APRÈS modification
    ls -lah $1

Rappels et compléments

Testez les commandes suivantes, et comprenez le résultat :

  1. echo *
  2. echo xx ls zz 
  3. echo "xx" "ls" "zz" 
  4. echo "xx ls zz" 
  5. echo xx 'ls' zz 
  6. echo xx `ls` zz 
  7. echo xx $(ls) zz
  8. date > xxx ; cat xxx (faire deux ou trois fois de suite)
  9. date >> xxx ; cat xxx (faire deux ou trois fois de suite)

La commande read permet de lire une chaîne au clavier et de l'affecter à une variable. Par exemple :

echo -n "Entrer votre nom: "
read nom
echo "Votre nom est $nom"

Exercices

  1. Le fichier liste contenant une liste de noms de fichiers, quel va être l'effet de la commande « cat $(cat liste) >resultat » ?
    Cette commande va concaténer (dans le fichier resultat) les fichiers dont les noms sont dans liste.
Dernière modification : 15/11/2016

Semaine du lendi 7 novemb' 2016 : CM n°8 (Cumul=12h)

Le contrôle n°2 aura lieu le vendredi 11 novembre, de 15h00 à 17h00, en salle C.11.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Exercices

  1. Le fichier liste contenant une liste de noms de fichiers, quel va être l'effet de la commande « cat $(cat liste) >resultat » ?
    Cette commande va concaténer (dans le fichier resultat) les fichiers dont les noms sont dans liste.
  2. Écrire un script shell qui prend en paramètre 2 entiers et affiche leur somme.
    echo $(($1+$2))
  3. Rediriger la sortie standard vers un fichier :
    • Créer un fichier dir.txt qui contient la liste plate des fichiers du répertoire courant.
      ls > dir.txt
    • Ajouter en fin du fichier précédent : une ligne vide, un trait constitué de symboles « = », et une autre ligne vide.
      echo >> dir.txt
      echo "==============" >> dir.txt
      echo >> dir.txt
    • Ajouter en fin du fichier précédent une liste détaillée des fichiers du répertoire courant.
      ls -lah >> dir.txt
  4. Écrire un script qui crée un fichier date.txt qui contient la date du moment où on exécute le script.
    #!/bin/bash
    date > date.txt
  5. Écrire un script qui, lors de son exécution, donne la date et l'heure, la liste de tous les utilisateurs connectés et le temps passé depuis le lancement du système (uptime). Enfin, le script doit sauvegarder cette information dans un journal.
    #!/bin/bash
    date
    date >> log.txt
    who
    who >> log.txt
    uptime
    uptime >> log.txt
    echo "=======================" >> log.txt
  6. Écrire un script qui concatène dans le premier les trois fichiers passés en paramètre.
    #!/bin/bash
    cat $2 $3 >> $1
  7. Écrire un script qui demande trois noms de fichiers et qui concatène les deux premiers dans le troisième.
    #!/bin/bash
    echo -n "Nom du premier fichier : "
    read un
    echo -n "Nom du deuxième fichier : "
    read deux
    echo -n "Nom du fichier destination : "
    read trois
    cat $un $deux > $trois
  8. Écrivez un script shell qui demande à l'utilisateur de taper deux noms de répertoire, puis recopie l'intégralité du contenu du premier répertoire dans le deuxième.
    echo -n "Premier répertoire : "
    read premier
    echo -n "Deuxième répertoire : "
    read deuxieme
    cp -R $premier/* $deuxieme/
Dernière modification : 15/11/2016

Semaine du lendi 7 novemb' 2016 : TD n°8 (Cumul=12h)

Le contrôle n°2 aura lieu le vendredi 11 novembre, de 15h00 à 17h00, en salle C.11.
Le contrôle se déroulera dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Exercices

Tester ces exercices faits lors du CM précédent

  1. Écrire un script shell qui prend en paramètre 2 entiers et affiche leur somme.
    echo $(($1+$2))
  2. Écrire un script qui crée un fichier date.txt qui contient la date du moment où on exécute le script.
    #!/bin/bash
    date > date.txt
  3. Écrire un script qui, lors de son exécution, donne la date et l'heure, la liste de tous les utilisateurs connectés et le temps passé depuis le lancement du système (uptime). Enfin, le script doit sauvegarder cette information dans un journal.
    #!/bin/bash
    date
    date >> log.txt
    who
    who >> log.txt
    uptime
    uptime >> log.txt
    echo "=======================" >> log.txt
  4. Écrire un script qui demande trois noms de fichiers et qui concatène les deux premiers dans le troisième.
    #!/bin/bash
    echo -n "Nom du premier fichier : "
    read un
    echo -n "Nom du deuxième fichier : "
    read deux
    echo -n "Nom du fichier destination : "
    read trois
    cat $un $deux > $trois
  5. Écrivez un script shell qui demande à l'utilisateur de taper deux noms de répertoire, puis recopie l'intégralité du contenu du premier répertoire dans le deuxième.
    echo -n "Premier répertoire : "
    read premier
    echo -n "Deuxième répertoire : "
    read deuxieme
    cp -R $premier/* $deuxieme/

Exercice à faire

  1. Même question que le premier exercice du TD précédent, mais le script doit garder dans un fichier une trace des fichiers traités (on parle de journal, ou de fichier de log), sous la forme d'une liste des noms de fichiers, chaque nom étant suivi sur la même ligne de la date où il a été traité, et sur la ligne suivante de l'état des droits avant modification.
    #!/bin/bash
    echo -n "$1 : " >> log.txt
    date >> log.txt
    echo Droits de $1 AVANT modification
    ls -lah $1
    echo
    ls -lah $1 >> log.txt
    echo >> log.txt
    echo Changement des droits en cours....
    chmod go-rwx $1
    echo
    echo Droits de $1 APRÈS modification
    ls -lah $1

Encore plus loin dans les scripts shell

La boucle for

La boucle for affecte successivement à une variable chaque chaîne de caractères trouvée dans une liste de chaînes, et exécute les commandes une fois pour chaque chaîne.

for var in liste de chaînes
do commandes
done
Il n'est pas nécessaire d'aller à la ligne.
Par exemple
for i in *
do
   echo $i
done
ou
for i in * ; do echo $i ; done

Faites d'autres essais, en remplaçant par exemple l'étoile de la première ligne par :

  1. « xx ls zz »,
  2. « "xx" "ls" "zz" »,
  3. « "xx ls zz" »,
  4. « xx 'ls' zz »,
  5. « xx `ls` zz ».
  6. « xx $(ls) zz ».

Attention : dans le quatrième exemple il s'agit de l'apostrophe classique (la touche du 4), dans le cinquième il s'agit du caractère back quote (AltGr + 7).

Autres exemples à tester :

  1. « echo {4..23} ».
  2. « echo {-2..12..3} ».
  3. « for i in {6..15} ; do echo $i ; done ».

La boucle while existe aussi

#!/bin/bash
while [ -z $reponse ] || [ $reponse != 'oui' ]
do
   read -p 'Dites oui : ' reponse
done
echo "Bravo..."

Syntaxe des tests

(source : Programmation du shell : Tests et conditions [http://www.xrings.net/xrings/article.php3?id_article=225])

Tests sur les fichiers (et sur les répertoires)

  • -e fichier : Vrai si le fichier/répertoire existe.
  • -s fichier : Vrai si le fichier à une taille supérieure à 0.
  • -z fichier : Vrai si le fichier fait 0 octet (donc si il est vide).
  • -r fichier : Vrai si le fichier/répertoire est lisible.
  • -w fichier : Vrai si le fichier/répertoire est modifiable.
  • -x fichier : Vrai si le fichier est exécutable ou si le répertoire est accessible.
  • -O fichier : Vrai si le fichier/répertoire appartient à l’utilisateur.
  • -G fichier : Vrai si le fichier/répertoire appartient au groupe de l’utilisateur.
  • -b nom : Vrai si nom représente un périphérique (pseudo-fichier) de type bloc (disques et partitions de disques généralement).
  • -c nom : Vrai si nom représente un périphérique (pseudo-fichier) de type caractère (terminaux, modems et port parallèles par exemple).
  • -d nom : Vrai si nom représente un répertoire.
  • -f nom : Vrai si nom représente un fichier.
  • -L nom : Vrai si nom représente un lien symbolique.
  • -p nom : Vrai si nom représente un tube nommé.
  • fichier1 -nt fichier2 : Vrai si les deux fichiers existent et si fichier1 est plus récent que fichier2.
  • fichier1 -ot fichier2 : Vrai si les deux fichiers existent et si fichier1 est plus ancien que fichier2.
  • fichier1 -ef fichier2 : Vrai si les deux fichiers représentent un seul et même fichier.

Tests sur les entiers

Il y a erreur si ce ne sont pas des entiers autour de l’opérateur.
  • entier1 -eq entier2 : Vrai si entier1 est égal à entier2.
  • entier1 -ge entier2 : Vrai si entier1 est supérieur ou égal à entier2.
  • entier1 -gt entier2 : Vrai si entier1 est strictement supérieur à entier2.
  • entier1 -le entier2 : Vrai si entier1 est inférieur ou égal à entier2.
  • entier1 -lt entier2 : Vrai si entier1 est strictement inférieur à entier2.
  • entier1 -ne entier2 : Vrai si entier1 est différent de entier2.

Tests sur les chaînes de caractères

Encadrez la chaîne par des guillemets !
  • -n "chaîne" : Vrai si la chaîne n’est pas vide.
  • -z "chaîne" : Vrai si la chaîne est vide.
  • "chaine1" = "chaine2" : Vrai si les deux chaînes sont identiques.
  • "chaine1" != "chaine2" : Vrai si les deux chaînes sont différentes.

Exercices

  1. Écrire un script shell qui affichera 5,4,3,2,1 en utilisant une boucle for.
    for i in {5..1..-1} ; do echo $i ; done
  2. Écrire un script qui crée un fichier liste (sans extension) qui contient la liste des fichiers *.txt du répertoire dans lequel il est exécuté. Pour chaque fichier *.txt, on donnera le nom sur une ligne, puis les 4 premières lignes du fichier, et on séparera du suivant par une ligne constituée de symboles « = ».
    #!/bin/bash
    echo "" > liste
    for x in *.txt
    do
     echo $x
     echo $x >> liste
     head -n4 $x >> liste
     echo ======================================== >> liste
    done
  3. Écrire un script shell qui affichera 5,4,3,2,1 en utilisant une boucle while.
    x=5
    while [ $x -ge 1 ]
       do
         echo $x
         x=$(($x-1))
    done
  4. Écrire un script qui prend en paramètre un entier et affiche l'entier en ordre inverse (123 -> 321).
    x=$1
    while [ $x -gt 9 ]
       do
         echo -n $(($x%10))
         x=$(($x/10))
    done
    echo $x
  5. Écrire un script qui prend en paramètre un entier et affiche la somme des chiffres qui le compose (123 -> 1+2+3 = 6).
    x=$1
    t=0
    while [ $x -gt 9 ]
       do
         t=$(($t+%10))
         x=$(($x/10))
    done
    echo $(($x+$t))

Toujours plus loin dans les scripts shell

La structure « if » existe aussi.

#!/bin/bash
if [ ! -e "$1" ]
 then
  echo "$1 n'existe pas"
elif [ -f "$1" ]
 then
  echo "$1 est un fichier"
elif [ -d "$1" ]
 then
  echo "$1 est un repertoire"
fi

Exercices

  1. Écrire un script qui dit pour chaque élément du répertoire courant si c'est un dossier ou un fichier.
    #!/bin/bash
    for i in *
      do
       if [ -f "$i" ]
        then
         echo "$i est un fichier"
       elif [ -d "$i" ]
        then
         echo "$i est un repertoire"
       fi
     done
  2. Réaliser une exploration récursive du répertoire courant.
    #!/bin/bash
    for x in $1/*
    do
      echo $2 $x
      if [ -d "$x" ]
       then
        echo $2 $x est un repertoire
        sh $0 $x "$2 + + "
      fi
    done

    On lance le script avec le paramètre « . » (répertoire courant).
    Remarque : $0 est le nom du script en cours d'exécution.
  3. Créer un script qui demande à l'utilisateur de saisir une note et qui affiche un message en fonction de cette note : « très bien » si la note est entre 16 et 20, « bien » lorsqu'elle est entre 14 et 16, « assez bien » si la note est entre 12 et 14, « moyen » si la note est entre 10 et 12, « insuffisant » si la note est inférieur à 10.
    read -p "Entrez votre note : " note
    if [ "$note" -ge 16 ]; then
       echo "très bien"
    elif [ "$note" -ge 14 ]; then
       echo "bien"
    elif [ "$note" -ge 12 ]; then
       echo "assez bien"
    elif [ "$note" -ge 10 ]; then
       echo "moyen"
    else
       echo "insuffisant"
    fi
  4. Écrire un script qui dit si le nombre passé en paramètre est premier.
    flag=0
    i=2
    while [ $flag -eq 0 ] && [ $(($i*$i)) -lt $1 ]
       do
         if [ $(($1 % $i)) -eq 0 ]
           then
            flag=1
         fi
         i=$(($i+1))
    done
    if [ $flag -eq 0 ]
       then
         echo "$1 est premier"
       else
         echo "$1 n'est pas premier"
    fi
  5. Écrire un script qui énumére tous les nombres premiers compris entre les deux entiers passés en paramètres.
    echo "Les nombres premiers entre $1 et $2 sont : "
    for n in `seq $1 $2`
       do
         flag=0
         i=2
         while [ $flag -eq 0 ] && [ $(($i*$i)) -lt $n ]
           do
             if [ $(($n % $i)) -eq 0 ]
               then
                 flag=1
             fi
             i=$(($i+1))
         done
         if [ $flag -eq 0 ]
           then
             echo -n "$n "
         fi
    done
    echo

Pour aller plus loin

Dernière modification : 15/11/2016

Semaine du lendi 14 novemb' 2016 : TD n°9 (Cumul=13,5h)

Patience...
Dernière modification : 31/8/2016

Semaine du lendi 21 novemb' 2016 : TD n°10 (Cumul=15h)