1 GPA435 Systèmes dexploitation et programmation de système Copyright, 2000 © Tony Wong, Ph.D. Chapitre 9 Exemples de programmation Bourne shell et nawk(1)
2 Exemples de programmation (1) Extraction des en-têtes de courriel Extraction des en-têtes de courriel Les courriels sont enregistrés dans le fichier /var/mail/$USER. Les courriels est séparé par une ligne blanche. Nous allons créer un petit programme Bourne shell afin de montrer les subtilités de sa programmation. Nous allons créer un petit programme Bourne shell afin de montrer les subtilités de sa programmation. Système dexploitation UNIX
3 Exemples de programmation (2) Système dexploitation UNIXOrdinogramme Nous utiliserons grep(1) et expr(1) pour extraire le champ Content-Length: Len-tête et le corps dun courriel sont séparés par une ligne blanche. Chaque en-tête est enregistré dans un fichier temporaire Nous ferons un bouclage pour passer « par dessus » le corps du courriel
4 Exemples de programmation (3) Système dexploitation UNIX Chaque en-tête est enregistré dans un fichier temporaire. Pour la longueur du corps du courriel: Chaque en-tête est enregistré dans un fichier temporaire. Pour la longueur du corps du courriel: LONGUEUR=`egrep 'Content-Length:' entetes${COMPTEUR}.tmp` LONGUEUR=`expr "$LONGUEUR" : 'Content-Length: \(.*\)'` Variable qui contiendra la longueur du corps Trouver la ligne désirée dans le corps Extraire la valeur située après le mot clé Content-Length:
5 Exemples de programmation (4) Pour passer au prochain en-tête. Il faut lire le nombre de caractères donnés par la valeur de Content-Length: Pour passer au prochain en-tête. Il faut lire le nombre de caractères donnés par la valeur de Content-Length: read DUMMY :: : CAR_LU=`/usr/ucb/expr length "$DUMMY"` CAR_LU=`/usr/ucb/expr length "$DUMMY"` TOTAL=`expr "$TOTAL" + "$CAR_LU"` TOTAL=`expr "$TOTAL" + "$CAR_LU"` TOTAL=`expr "$TOTAL" + 1` TOTAL=`expr "$TOTAL" + 1` Système dexploitation UNIX Lire une ligne du fichier dentrée et faire la somme des caractères lus. Noublier pas de compter le caractère Enter
6 Exemples de programmation (5) Attention! Par défaut la commande read(1) utilise les caractères Espace, Tab et Enter comme séparateur de champs. Attention! Par défaut la commande read(1) utilise les caractères Espace, Tab et Enter comme séparateur de champs. La commande read(1) ne conserve quune seule copie des séparateurs dans une ligne lue. Ainsi, La commande read(1) ne conserve quune seule copie des séparateurs dans une ligne lue. Ainsi, cette ligne contient des espaces Système dexploitation UNIX Ligne originale dans le fichier dentrée Ligne lue par read(1). Donc, il y pertes de caractères !!!!
7 Exemples de programmation (6) Système dexploitation UNIX Solution pour ce problème ? Solution pour ce problème ? Régler la variable globale Bourne shell IFS (Internal Field Separator). Normalement la variable IFS est réglée à Espace, Tab et Enter. Il nous faut régler IFS à Enter seulement. Voici comment: IFS="" Oui. Il faut taper la touche Enter avant de fermer les guillemets
8 Système dexploitation UNIX#!/bin/sh # ex_entete # Programme pour extraire l'en-tete des courriels. # # Fonction Bourne shell pour montrer l'usage de ce programme # usage () { echo "\nex_entete [-hkn] courriers\n" echo "\nex_entete [-hkn] courriers\n" echo "-h = cet affichage" echo "-h = cet affichage" echo "-k = garder les en-tetes dans des fichiers distincts" echo "-k = garder les en-tetes dans des fichiers distincts" echo " portant les noms entetes1.tmp, entetes2.tmp..." echo " portant les noms entetes1.tmp, entetes2.tmp..." echo "-n = pas d'affichage a la sortie standard" echo "-n = pas d'affichage a la sortie standard" echo "courriers = fichier contenant les courriels a traiter\n" echo "courriers = fichier contenant les courriels a traiter\n" echo "Par defaut, les en-tetes sont affiches a la sortie" echo "Par defaut, les en-tetes sont affiches a la sortie" echo "standard separes par more(1)\n" echo "standard separes par more(1)\n" exit 1 exit 1} Lusage du programme est affiché par une fonction Bourne shell
9 Système dexploitation UNIX# # S'il y a pas d'options donnees a la ligne de commande... # [ $# -gt 0 ] || usage # # Aller chercher les options de la ligne de commande... # while getopts hkn OPTION do case "$OPTION" in case "$OPTION" in h | \?) usage ;; h | \?) usage ;; k) GARDE=OUI ;; k) GARDE=OUI ;; n) PAS_SORTIE=OUI ;; n) PAS_SORTIE=OUI ;; esac esacdone# # Aller chercher le fichier contenant les courriels... # shift `expr "$OPTIND" - 1` [ -z "$1" ] && usage # pas de fichier donne a la ligne de commande Détection des options données sur la ligne de commande.
10 Système dexploitation UNIX# # Quelques variables globales... #CONTINUE=VRAICOMPTEUR=1 # C'est tres important! Il faut regler IFS (separateur de champs pour # la commande read(1)) avec le caractere Enter. Sinon, read(1) va # ignorer les caracters Espace et Tab. Dans le corps d'un courriel, # Espace et Tab sont comptes !!! IFS="" while [ "$CONTINUE" = VRAI ] do read LIGNE || exit 0 read LIGNE || exit 0 # detecter la ligne blanche qui delimite l'en-tete # detecter la ligne blanche qui delimite l'en-tete if [ -z "$LIGNE" ] if [ -z "$LIGNE" ] then then # # Obtenir la longueur du courriel # Obtenir la longueur du courriel # LONGUEUR=`egrep 'Content-Length:' entetes${COMPTEUR}.tmp` LONGUEUR=`egrep 'Content-Length:' entetes${COMPTEUR}.tmp` LONGUEUR=`expr "$LONGUEUR" : 'Content-Length: \(.*\)'` LONGUEUR=`expr "$LONGUEUR" : 'Content-Length: \(.*\)'` [ -z "$PAS_SORTIE" ] && more -w < entetes${COMPTEUR}.tmp [ -z "$PAS_SORTIE" ] && more -w < entetes${COMPTEUR}.tmp [ -z "$GARDE" ] && /bin/rm -f entetes${COMPTEUR}.tmp [ -z "$GARDE" ] && /bin/rm -f entetes${COMPTEUR}.tmp COMPTEUR=`expr "$COMPTEUR" + 1` COMPTEUR=`expr "$COMPTEUR" + 1` Noubliez pas de régler correctement la variable Bourne shell IFS OK. L en-tête est terminé. Aller chercher la longueur du corps...
11 Système dexploitation UNIX TOTAL=0 TOTAL=0 while [ "$TOTAL" -lt "$LONGUEUR" ] while [ "$TOTAL" -lt "$LONGUEUR" ] do do read DUMMY read DUMMY if [ $? -ne 0 ] if [ $? -ne 0 ] then then echo "La boite aux lettres est brisee !" echo "La boite aux lettres est brisee !" echo "Programme termine prematurement." echo "Programme termine prematurement." exit 1 exit 1 else else CAR_LU=`/usr/ucb/expr length "$DUMMY"` CAR_LU=`/usr/ucb/expr length "$DUMMY"` TOTAL=`expr "$TOTAL" + "$CAR_LU"` TOTAL=`expr "$TOTAL" + "$CAR_LU"` TOTAL=`expr "$TOTAL" + 1` TOTAL=`expr "$TOTAL" + 1` fi fi done done # Sauter par dessus la derniere ligne blanche # Sauter par dessus la derniere ligne blanche read DUMMY read DUMMY else else # # Ecrire l'en-tete dans le fichier temporaire # Ecrire l'en-tete dans le fichier temporaire # echo "$LIGNE" >> entetes${COMPTEUR}.tmp echo "$LIGNE" >> entetes${COMPTEUR}.tmp fi fi done < "$1" Lire le nombre de caractères indiqués par la valeur de « Content- Length: ». Le fichier dentrée est lu ligne par ligne. Noubliez pas dajouter le caractère Enter dans le comptage. Cest une ligne de len- tête
12 Exemples de programmation (7) Système dexploitation UNIX Pour terminer une tâche errante, nous devons utiliser la commande ps(1) et kill(1). Pour terminer une tâche errante, nous devons utiliser la commande ps(1) et kill(1). La commande ps(1) permet dobtenir le PID du processus à fautif. La commande ps(1) permet dobtenir le PID du processus à fautif. La commande kill(1) permet lélimination du processus à laide de son PID. La commande kill(1) permet lélimination du processus à laide de son PID.
13 Exemples de programmation (8) Système dexploitation UNIX Cest le champ $1 pour nawk(1) lorsque la commande utilisée est ps -e
14 Exemples de programmation (8) Système dexploitation UNIX Pour terminer une tâche dont le PID est 4003: Pour terminer une tâche dont le PID est 4003: kill Le signal à envoyer au processus (par exemple) Le PID du processus à « tuer »
15 Exemples de programmation (9) Système dexploitation UNIX Le problème: il faut connaître le PID du processus errant !!! Le problème: il faut connaître le PID du processus errant !!! Nous allons écrire un programme Bourne shell capable de « tuer » un ou plusieurs processus par leur nom au lieu de leur PID. Nous allons écrire un programme Bourne shell capable de « tuer » un ou plusieurs processus par leur nom au lieu de leur PID. Mieux encore, nous pouvons aussi utiliser une expression générique pour spécifier les noms de processus. Mieux encore, nous pouvons aussi utiliser une expression générique pour spécifier les noms de processus.
16 Système dexploitation UNIX#!/bin/sh # Par mesure de securite... PATH=/bin:/usr/bin:/usr/5bin:. # Les PID retournes par nawk sont separes # par des... IFS=' '# '# # # Traiter les options de la ligne de commandes # case $1 in "") echo 'Utilisation: zap [-n] expr' 1>&2 "") echo 'Utilisation: zap [-n] expr' 1>&2 exit 1 ;; exit 1 ;; # si le numero du signal est donne... # si le numero du signal est donne... -*) SIG=$1 -*) SIG=$1 shift shiftesac La variable IFS réglée à Espace... Traitement des options du programmes
17 Système dexploitation UNIX# # Trouver les PID des processus identifies par leur nom # numjob=`ps -e | egrep "$1" | nawk '{print $1}'` # # Continuer le traitement seulement si les processus # sont trouves # if [ "$numjob" ] then set $numjob # les PID seront separes par des set $numjob # les PID seront separes par des # nouvelles lignes # nouvelles lignes while [ $# -ne 0 ] while [ $# -ne 0 ] do do if [ $1 -lt $$ ] # tuer seulement les processus lances if [ $1 -lt $$ ] # tuer seulement les processus lances then # avant l'execution de ce script then # avant l'execution de ce script kill $SIG $1 kill $SIG $1 fi fi shift shift done doneelse echo "Ne trouve le ou les processus" 1>&2 echo "Ne trouve le ou les processus" 1>&2fi La recherche du PID des processus à éliminer Mettre les PID trouvés comme des paramètres de position
18 Exemples de programmation (10) Système dexploitation UNIX Lintégration UNIX - PC est un but recherché depuis longtemps. Lintégration UNIX - PC est un but recherché depuis longtemps. Une réalité est larrimage des systèmes de fichiers UNIX et PC. Une réalité est larrimage des systèmes de fichiers UNIX et PC. Le système NFS (Network FileSystem) est le dénominateur commun entre le monde UNIX et le monde PC. Le système NFS (Network FileSystem) est le dénominateur commun entre le monde UNIX et le monde PC. La famille des produits HummingBird Maestro permet lintégration des systèmes de fichiers NTFS et UFS via le NFS. La famille des produits HummingBird Maestro permet lintégration des systèmes de fichiers NTFS et UFS via le NFS.
19 Exemples de programmation (11) Système dexploitation UNIX Un répertoire UNIX ( $HOME ) en provenance du serveur UNIX lca0.lca.etsmtl.ca
20 Exemples de programmation (12) Système dexploitation UNIX Pour réaliser la connexion des systèmes de fichiers: Pour réaliser la connexion des systèmes de fichiers: Une machine UNIX joue le rôle du serveur NFS Une machine UNIX joue le rôle du serveur NFS Une ou plusieurs machines PC jouent le rôle de clients NFS Une ou plusieurs machines PC jouent le rôle de clients NFS Pour le serveur NFS (UNIX): Pour le serveur NFS (UNIX): Il faut démarrer le programme dauthentification NFS nommé hclnfsd De plus, les programmes statd et lockd doivent être démarrés au préalable.
21 Exemples de programmation (13) Système dexploitation UNIX Dans notre cas, le programme dauthenti- fication NFS hclnfsd est invoqué automatiquement à l aide dun programme Bourne shell. Dans notre cas, le programme dauthenti- fication NFS hclnfsd est invoqué automatiquement à l aide dun programme Bourne shell. Nous allons créer un programme capable de détecter la présence de statd et lockd avant le lancement de hclnfsd. Nous allons créer un programme capable de détecter la présence de statd et lockd avant le lancement de hclnfsd. De plus, on sassure quil nexiste pas de hclnfsd déjà en mémoire avant son lancement. De plus, on sassure quil nexiste pas de hclnfsd déjà en mémoire avant son lancement.
22 Exemples de programmation (14) Système dexploitation UNIX Normalement, les programmes statd et lockd sont toujours en mémoire. Normalement, les programmes statd et lockd sont toujours en mémoire. Ils sont lancés au démarrage de la machine UNIX Résultats affichés par ps -e Note: La colonne PID est le champ $1 pour nawk(1) statd permet lobtention des attributs de fichiers. lockd permet le verrouillage des fichiers.
23 Système dexploitation UNIX#!/bin/sh # S991hclnfsd.server # # Copyright (c) 1999 par Tony Wong # Departement de genie de production automatisee # Ecole de technologie superieure # Universite du Quebec ## # Demarrage du service d'authentification NFS pour PC # (hclnfsd) de HummingBird Communications Ltd Daccord… cest de la publicité gratuite...
24 Système dexploitation UNIX # arret() : Fonction qui termine l'execution d'un ou # ou plusieurs processus hclnfsd arret() { /usr/bin/ps -e | /usr/bin/ps -e | /usr/bin/nawk ' /usr/bin/nawk ' BEGIN { i = 0 } BEGIN { i = 0 } /hclnfsd/ { PID[i++] = $1 } /hclnfsd/ { PID[i++] = $1 } END { for (i in PID) { END { for (i in PID) { print "Termine processus ",PID[i] print "Termine processus ",PID[i] system ("kill " PID[i]) system ("kill " PID[i]) } }' }'} trouve() { ps -e | grep $1 > /dev/null 2>&1 } Fonction Bourne shell utilisant nawk(1) pour éliminer les instances de hclnfsd déjà en mémoire Voici comment exécuter une commande ou programme UNIX à l intérieur de nawk(1). Noter le passage de paramètres nawk(1) vers la commande UNIX. Cette fonction retourne un statut de sortie 0 si le nom du processus passé en paramètre existe en mémoire
25 Système dexploitation UNIX case "$1" in 'start') if trouve "statd" -a trouve "lockd" if trouve "statd" -a trouve "lockd" then then if trouve "hclnfsd" if trouve "hclnfsd" then then echo "hclnfsd deja en service !" echo "hclnfsd deja en service !" echo "Arreter le service d'abord" echo "Arreter le service d'abord" else else hclnfsd -A -X hclnfsd -A -X fi fi else else echo "Services de support inexistants" echo "Services de support inexistants" echo "(statd et/ou lockd)" echo "(statd et/ou lockd)" fi fi ;; ;;'stop')arret;;*) echo "Usage: S991hclnfsd.server { start | stop }" ;;esac Sassurer quils sont déjà en mémoire Lancer le programme dauthentification NFS Éliminer hclnfsd de la mémoire
26 Exemples de programmation (15) Pour en savoir plus sur lintégration multi- plateforme, le NFS, le HummingBird Maestro, etc. : Pour en savoir plus sur lintégration multi- plateforme, le NFS, le HummingBird Maestro, etc. : Système dexploitation UNIX