Systèmes d’exploitation et programmation de systèmes -GPA435- Cours #6: Éléments de programmation (Partie 3) Enseignant: Jean-Philippe Roberge Jean-Philippe Roberge - Mai 2014
Planification du cours #6 Petite révision du cours #5: Fonctions utilisateur du shell Neutralisation des caractères Commandes exec et trap Déverminage Contenu du cours #6: ShellShock Décodage des paramètres Évaluation répétitive Commande expr Synthèse et révision en vue de l’examen intra Renseignements par rapport à l’examen intra et exercices 2 Jean-Philippe Roberge - Mai 2014
Nous pouvons rendre la programmation plus structurée en utilisant des fonctions La syntaxe est: Nom_fonction () { commandes commandes} Une fonction utilisateur joue le rôle d’une sous-routine. 3 Révision du cours #5 (1) Fonctions utilisateur
Passage des paramètres dans une fonction utilisateur o Par variables globales ERRNO=1234 gestion_erreur () { case "$ERRNO" in case "$ERRNO" in 0) ;; # pas d'erreur 0) ;; # pas d'erreur 101) echo "Répertoire inexistant" ;; 101) echo "Répertoire inexistant" ;; 102) echo "Permission d'écriture obligatoire";; 102) echo "Permission d'écriture obligatoire";; *) echo "Code d'erreur inconnu" *) echo "Code d'erreur inconnu" exit 1 exit 1 ;; ;; esac esac} while [ $ERRNO -ne 0 ] do repertoire; ERRNO=$? repertoire; ERRNO=$? gestion_erreur gestion_erreurdone 4 1) Le contenu de la variable globale ERRNO est visible par la fonction gestion_erreur() puisqu’elle a été déclarée avant la définition de la fonction. 2) La fonction gestion_erreur() peut traiter le contenu de la variable globale ERRNO. Révision du cours #5 (2) Fonctions utilisateur
Passage des paramètres dans une fonction utilisateur o Par paramètres de position gestion_erreur () { case "$1" in case "$1" in 0) ;; # pas d'erreur 0) ;; # pas d'erreur 101) echo "Répertoire inexistant" ;; 101) echo "Répertoire inexistant" ;; 102) echo "Permission d'écriture obligatoire";; 102) echo "Permission d'écriture obligatoire";; *) echo "Code d'erreur inconnu" *) echo "Code d'erreur inconnu" exit 1 exit 1 ;; ;; esac esac}ERRNO=123 while [ $ERRNO -ne 0 ] do repertoire; ERRNO=$? repertoire; ERRNO=$? gestion_erreur "$ERRNO" gestion_erreur "$ERRNO"done 5 1) Le contenu de la variable ERRNO est passé à la fonction gestion_erreur() comme un paramètre de position. 2) La fonction gestion_erreur() reçoit le contenu de la variable ERRNO dans sa variable de position $1. Révision du cours #5 (3) Fonctions utilisateur
Passage des paramètres dans une fonction utilisateur o Par paramètres de position o De façon générale: # définition de la fonction funcA () { # $# le nombre de paramètres de position # $* et la ligne des paramètres de position # $1 reçoit le contenu de $par1 # $2 reçoit le contenu de $par2 # $3 reçoit le contenu de $par3 # et ainsi de suite } # utilisation de la fonction funcA par1 par2 par3 6 Donc, pour une fonction utilisateur, les paramètres de position se comportent exactement comme un programme Révision du cours #5 (4) Fonctions utilisateur
Ainsi, le symbole \ permet la neutralisation du caractère qui le suit. 7 Le symbole \ a effectivement neutralisé le premier méta- caractère & mais pas le 2 e. On dit que \ est un neutralisateur de simple (1 seul) caractère. Révision du cours #5 (5) Fonctions utilisateur
Nous pouvons neutraliser plus d’un caractère à la fois par les guillemets et les apostrophes. Guillemets Guillemets o Neutralise la signification spéciale du caractère ESPACE; o Permet la substitution des variables et des commandes; o Permet l’utilisation du neutralisateur \. 8 Bug 1: $CAD est interprété comme le contenu de la variable CAD et non pas dollar canadien Bug 2: Le caractère ESPACE a séparé la chaîne de caractères en 2 parties L’utilisation des guillemets et de \ permet de solutionner ce problème. Révision du cours #5 (6) Neutralisation des caractères
Nous pouvons neutraliser plus d’un caractère à la fois par les guillemets et les apostrophes. Apostrophes Apostrophes o Neutralise la signification spéciale du caractère ESPACE; o Empêche la substitution des variables et des commandes; o Neutralise le neutralisateur \. 9 Les apostrophes ont effectivement neutralisé le neutralisateur \ et empêché la substitution de la variable CAD. Révision du cours #5 (7) Neutralisation des caractères
D’autres exemples qui aident à la compréhension de la neutralisation des méta- caractères 10 gpa435> MACHINE=`hostname` gpa435 > echo La machine \'$MACHINE\' est en panne La machine 'my-ubuntu' est en panne gpa435 > echo La machine "'$MACHINE'" est en panne La machine 'my-ubuntu' est en panne gpa435 > echo La machine '$MACHINE' est en panne La machine $MACHINE est en panne gpa435 > echo "La machine '$MACHINE' est en panne" La machine 'my-ubuntu' est en panne gpa435 > echo 'La machine $MACHINE est en panne' La machine $MACHINE est en panne gpa435 > echo 'La machine '$MACHINE' est en panne' La machine my-ubuntu est en panne Révision du cours #5 (8) Neutralisation des caractères
Dans un programme, la commande exec(1) permet l’exécution d’une commande sans la création d’un nouveau processus. Vous pouvez donc passer des paramètres du programme à la commande à exécuter. Attention! Ce n’est pas un appel de sous-routine car le contrôle ne revient pas au programme. 11 Révision du cours #5 (9) Commande exec
Voici un exemple: 12 La ligne exec date exécute la commande date et lui passe le contrôle. Résultat: On voit que la ligne echo "Fin du programme" n’est jamais exécutée. Révision du cours #5 (10) Commande exec
La commande exec(1) sert aussi à rediriger les entrées-sorties standard d’une façon globale. Différentes syntaxes: exec no_desc> nom_fich exec no_desc> nom_fich exec no_desc>&no_desc exec no_desc>&no_desc exec no_desc>> nom_fich exec no_desc>> nom_fich exec no_desc< nom_fich exec no_desc< nom_fich exec no_desc<&no_desc exec no_desc<&no_desc 13 Légende: no_desc : numéro descripteur nom_fich : nom de fichier >, >&, >>,, >&, >>, <, <& : opérateurs de redirection Révision du cours #5 (11) Commande exec es/reprenez-le-controle-a-l-aide- de-linux/les-flux-de-redirection
Un exemple: 14 À partir de ce point, tous les messages d’erreur seront envoyés dans un fichier nommé errmsg.txt. On pourra en faire de même pour rediriger d’une façon globale la sortie standard et l’entrée standard en utilisant les opérateurs de redirection appropriés. Révision du cours #5 (12) Commande exec
La commande trap(1) est fort utile pour la programmation La syntaxe: trap ‘commandes’ signaux o commandes est un ensemble de commandes Linux; o signaux sont des numéros (entiers). À la réception d’un signal par le programme, les commandes entre apostrophes sont exécutées. 15 Révision du cours #5 (13) Commande trap
Voici quelques signaux disponibles 16 SignalSignification ctrl-c Interrompre le programme ctrl-y Suspendre (bloque) le programme lorsqu’il tentera de lire l’entrée standard ctrl-z Suspendre (bloque) le programme 1 Couper le lien logique avec le terminal 2 Interrompre le programme 9 Tuer (kill) le programme 15 Fin (normale) du programme 17, 19, 23 Arrêter le programme Les signaux 9, 17, 19 et 23 ne peuvent être interceptés par trap(1), Saviez-vous pourquoi? Révision du cours #5 (14) Commande trap
Exemple d’utilisation de trap(1) 17 Ce programme ne fait rien pendant 100 secondes (sleep 100). Envoyez le signal ctrl-c au programme. La commande trap(1) interceptera le signal et affiche un message à la sortie standard. Révision du cours #5 (15) Commande trap
Exemple d’utilisation de trap(1) 18 Ce programme ne fait rien pendant 100 secondes (sleep 100). Envoyez le signal ctrl-z pour suspendre le programme. Entrer la commande bg pour exécuter le programme en arrière-plan. Entrer la commande fg pour exécuter le programme en avant-plan À la fin du programme, trap(1) affiche un message. Révision du cours #5 (16) Commande trap
Cours #6
Nom le plus répandu: ShellShock, se nomme aussi bashdoor et bashbug Bug de Bash, découvert le 12 septembre 2014! Divulgué le 24 septembre 2014 dernier. Grosse couverture médiatique. Moins de 24h après la divulgation du bug, plus de attaques sur plus de 1800 domaines provenant de 400 adresses IP (55% Chine & USA) En date du 30 septembre: pas moins de 1.5 millions d’attaques par jour (DDOS) 6 octobre: les serveurs de Yahoo sont compromis
Les programmes qui sont en cours d’exécution possèdent leur liste de variables d’environnement. Quand un programme lance un autre programme, il fournit normalement la liste des variables d’environnement à ce nouveau programme. De façon indépendante, Bash maintient également une liste de variables d’environnement, et également une liste de fonctions internes. Puisque Bash opère comme un interpréteur de commande et une commande, il est possible d’exécuter Bash à partir de lui-même. Lorsque cela survient, l’instance originale de Bash peut exporter les variables d’environnement et les fonctions internes dans la nouvelle instance de Bash. Les définitions de fonctions sont exportées en les encodants dans des variables d’environnement dont la valeur commence avec des parenthères suivi de la définition de la fonction.
En démarrant, la nouvelle instance de Bash va « scanner » ses variables d’environnement. Lorsqu’elle trouvera des variables dont la valeur débute par des parenthèses, elle effectuera la conversion variable fonction interne en créant un fragment de code et en l’exécutant. Problème: Les versions de Bash affectées ne vérifient pas au préalable que ladite définition de la fonction soit dans un format valide… Créant du même coup une faille de sécurité. Par conséquent, quelqu’un de mal intentionné à qui on donnerait l’opportunité d’exécuter Bash et en lui donnant la chance d’entrer des valeurs arbitraires dans les variables d’environnement pourrait faire du tort au système. Exemple, faille de sécurité:
Problèmes : Web server : plusieurs sont basés sur Bash et exécute des Bash scritps. Ssh-server: idem Autres… Attaques (jusqu’à maintenant…): Yahoo (DDOS) Akamai technologies (DDOS) United States Department of Defense (Script malveillant, balayage du contenu des serveurs) Plusieurs autres
Neutralisation (2 e visite) (1) Rappel: La neutralisation est nécessaire parce que certains caractères sont interprétés différemment par le shell et par les commandes. Il n’y a pas assez de caractères dans notre alphabet ! Donc, la neutralisation est nécessaire pour empêcher le shell de faire des substitutions inappropriées.
Neutralisation (2 e visite) (2)
Neutralisation (2 e visite) (3)
Neutralisation (2 e visite) (4)
Neutralisation (2 e visite) (5)
Redirection (2 e visite) (1)
Redirection (2 e visite) (2) Programme Bourne shell Redirection de l’entrée standard avec mot clé pour l’arrêt de lecture
Particularités: et "$*" (1) Lorsque utilisé entre guillemet, la variable et la variable $* n’ont pas la même signification. Pour "$*" l’interpréteur de commandes substitue les paramètres de position en leur entourant par des guillemets. Ce n’est pas le cas pour
Particularités: et "$*" (2)
Particularités: et "$*" (3) Le résultat n’est pas le même ! Truc: utilisez dans vos programmes Bourne shell. Truc: utilisez dans vos programmes Bourne shell.
Déverminage (1) Pour simplifier la recherche des erreurs dans un programme Bourne shell: Utiliser la commande set(1) pour activer les modes de déverminage. Les options disponibles sont:
Déverminage (2) Voici un exemple: Ce programme utilise l’option de déverminage -x.
Déverminage (3) Le résultat après l’exécution du programme précédent:
Décodage des paramètres (1) Il existe une commande simple pour le décodage systématique des paramètres de position. Il s’agit de la commande getopts(1). La syntaxe de cette commande: getopts chaîne_options NOMVARIABLE [paramètres] chaîne_options représente les options à reconnaître par getopts(1) NOMVARIABLE les options reconnues par getopts(1) sont placées dans cette variable parametres s’il existe, getopts(1) va tenter d ’extraire les options à partir de cet argument
Décodage des paramètres (2) On indique à getopts(1) de reconnaître les options -l, -q, -lq
Décodage des paramètres (3) Les résultats de ce programme:
Décodage des paramètres (4) Un autre exemple: install_lq2 [-l logfile -q] [nom_rep]
Décodage des paramètres (5) Résultat de l’exécution du programme précédent:
Évaluation répétitive (1) La commande eval(1) permet la substitution des variables et la substitution des commandes AVANT l’exécution d’une commande. Elle effectue également la neutralisation des caractères. Exemple: CMD=pwd eval "$CMD" &
Évaluation répétitive (2) On peut aussi créer des noms de variables pendant l’exécution du programme !
Évaluation répétitive (3)
Commande expr(1) Cette commande permet l’évaluation des expressions spécifiées par les arguments placés dans la ligne de commandes Evaluation logique et relationnelle, e.g.: expr $e1 \| $e2 (OU logique) expr $e1 \& $e2 (ET logique) expr $e1 \<= $e2 (relationnelle) etc…
Commande expr(1) Evaluation arithmétique: expr $e1 + $e2 (addition) expr $e1 \* $e2 (multiplication) Manipulation des chaînes: expr $e1 : $e2 (appariement) Trouver la chaîne $e2 dans la chaîne $e1. $e2 peut contenir des expressions régulières
Commande expr(1) Appariement des chaînes expr length $e1 (longueur) expr substr $e1pos ncar (sous-chaîne) expr index $e1 $e2 (position) Retourner la position de $e2 dans $e1
Commande expr(1) Exemple: $ A="J'aime le système Unix" $ expr length "$A" 22 $ expr "$A" : '.*le.*' 22 $ expr "$A" :.*le\(.*\) 0 $ expr "$A" : '.*le\(.*\)' système Unix $ echo '.*le\(.*\)'.*le\(.*\)
Commande expr(1) 1 #!/bin/sh 2 # Nom du programme : exprtest2 3 # exprtest2 : montrer l'utilisation de expr(1) pour 4 # obtenir le dernier membre d'une chemin de répertoire 5 # 6 7 echo "Donner un chemin de répertoire: \c" 8 read CHEMIN 9 DERNIER_MEMBRE=`expr "$CHEMIN" : '.*/\(.*\)' \| "$CHEMIN"` 10 echo "Le dernier membre de $CHEMIN est:\n$DERNIER_MEMBRE"
DERNIER_MEMBRE=`expr "$CHEMIN" : '.*/\(.*\)' \| "$CHEMIN"` DERNIER_MEMBRE=`expr e1 \| e2` e1 "$CHEMIN" : '.*/\(.*\) ’ e2 "$CHEMIN" Commande expr(1)
Examen intra Date: Mardi le 17 février 2014 Durée: 3 heures Documentation: Toute documentation permise Lieu: Local de cours habituel (A-1350) Contenu: Matière du cours 1 à 6 inclusivement Chapitres 1, 4, 5, 6 et 7 Questions par courriels à l’avance dans la mesure du possible 51 Jean-Philippe Roberge - Avril 2014
Exercices (1) Chapitre 1: Décrire dans vos mots ce qu’est: A) Le traitement en série B) Le traitement par lots C) Le traitement par lots multiprogrammés D) Le traitement en temps partagé Quels sont les trois moyens qu’ont les processus pour s’échanger des données ? Chapitre 4: Pourquoi mv./NomFich1./NomFich2 est une opération qui renomme un fichier alors que mv../NomFich1./Nomfich2 est une opération qui déplace un fichier? 52 Jean-Philippe Roberge - Avril 2014
Exercices (2) Chapitre 4 (suite) : Quelle est la différence entre les commandes A) man –s 1 ls B) man ls C) man –s 2 ls Chapitre 5 : Expliquer la commande suivante: chmod 754./* 2>/dev/null & Soit un script nommé programme, expliquez trois façons différentes de lancer son exécution. Expliquer et dire ce que fera la ligne de commande suivante: date | grep “Oct” 53 Jean-Philippe Roberge - Avril 2014
Exercices (3) Chapitre 5 (suite): Expliquer la commande suivante: chmod 754./* 2>/dev/null & Soit un script nommé programme, expliquez trois façons différentes de lancer son exécution. Expliquer et dire ce que fera la ligne de commande suivante: date | grep “Oct” Si le programme nommée dtpad est à la fois dans le répertoire /bin et dans le répertoire /usr/dt/bin. Lequel des deux programmes sera-t-il exécuté par l’interpréteur de commande en lançant l’instruction “dtpad” à la ligne de commande? Soit un fichier toto1.txt existant et toto2.txt inexistant. Que fera les lignes de commande suivante: cat toto1.txt toto2.txt 2>&1 1>sortie.txt cat toto1.txt toto2.txt 1>sortie.txt 2>&1 cat toto1.txt >sortie.txt | more 54 Jean-Philippe Roberge - Avril 2014
Exercices (4) Chapitre 5 (suite): Soit LOGFILE= log.txt et NOMFICHIER=Fich.txt. Expliquer les commandes suivante: echo " `date` : Un répertoire a été créé! " >> $LOGFILE touch `pwd`/travail/$NOMFICHIER && chmod 644 `pwd`/travail/$NOMFICHIER Chapitre 6: Expliquez les scripts Exemple* Quelle est la différence entre les méta-caractères \, ' ' et " " ? Donner un exemple d’application pour chacun de ces méta-caractères. Comment peut-on neutraliser les méta-caractères de la question précédente ? 55 Jean-Philippe Roberge - Avril 2014
Exercices (5) Chapitre 7: Que fait la commande ci-dessous, que contient Var2? Var1=pwd;Var2=`eval $Var1` 56 Jean-Philippe Roberge - Avril 2014
Exercices (6) Chapitre 7: Laquelle des commandes ci-dessous permet-elle l’affichage de la chaîne : ? is>> *\ echo ? is>> *\ echo ? "is">> *\\ echo \? is\>>\*\\ echo \? is\>\>\*\\ 57 Jean-Philippe Roberge - Avril 2014
Références [1] Présentations PowerPoint du cours GPA435, Tony Wong. [2] Notes de cours, GPA435 [3] Levasseur, Yan, Wiki GPA435: consulté en avril [4] Tanenbaum, A.S., Systèmes d’exploitation. Pearson Education France, [5] Stallings, W., Operating Systems : Internals and Design Principals. Upper Saddle River, NJ : Prentice Hall, [6] Références citées dans le premier chapitre des notes de cours. 58 Jean-Philippe Roberge - Avril 2014