CORRECTION examen M2 CCI 2013 - session 1 ----------------------------------------- 1.1 a) /usr/include/argp.h /usr/include/argz.h /usr/include/ar.h /usr/include/crypt.h <----- (attention affichage du nom complet, et * = 0 ou plus caractère) b) les 4 premiers fichiers qui contiennent la chaine 'ses' (sans le chemin cette fois) aliases.h cursesapp.h cursesf.h curses.h 1.2 a) les deux dernières colonnes (de séparateur :) sont affichées : /root:/bin/bash /usr/bin:/bin/sh ... /usr/games:/bin/sh b)trie le résultat précédent selon la première colonne /bin:/bin/sh ... /usr/sbin:/bin/sh 1.3 on peut commencer par n'attraper que les deux bouts qui nous intéressent en utilisant cut avec le délimiteur 'espace': date | cut -d\ -f 4-6 là je garde le "CEST" qui va me servir pour le sed d'apres : date | cut -d\ -f 4-6 | sed -e 's/^\(.*\)CEST\(.*\)/Annee \2, il est \1/' (n'importe quoi en début de ligne, qui sera la variable \2, suivi de CEST suivi de n'importe quoi, ce sera l'heure) ou, plus élégant : set $(date) ; echo "L'année est $6, il est $4" 1.4 #!/bin/bash ### Script shell #le nb d'arguments doit etre egal à 3 if [ ! $# -eq 3 ] ; then echo "wrong nb of args" exit -1 fi #calcul de la somme des deux premiers arguments sum=$(expr $1 + $2) if [ $sum -eq $3 ]; then echo "$3=$1+$2" else echo "$3!=$1+$2" fi c) faire la somme de tous les éléments sauf le dernier n'est pas très simple. il n'est pas possible de parler de $[$#] par exemple. #!/bin/bash ### Script shell #le nb d'arguments n'est pas testé #somme de tous les arguments sauf le dernier : sum=0; for i in $*; do sum=$(expr $sum + $i) dernier=$i done # on supprime le dernier élement de la somme sum=$(expr $sum - $dernier) if [ $dernier -eq $sum ]; then op="=" else op="!=" fi; #impression finale : initialisation de la chaine à  "dernier = " ou #"dernier != " chaine=$dernier$op chaine2="" cpt=1; #compter le nb d'args pour ne pas imprimer le dernier for i in $*; do if [ $cpt -eq 1 ] ; then chaine2=$1 else if [ $cpt -lt $# ]; then #inf strict chaine2=$chaine2+$i fi fi cpt=$(expr $cpt + 1) done #on imprime tout echo $chaine$chaine2 NB : on aurait pu utiliser la meme boucle pour calculer la somme et construire la chaine. On peut aussi utiliser une boucle "tq i < $#" Partie 2 : -------- 1.1 une possibilité : mkdir config mkdir TP mkdir TP/TP1 mkdir TP/TP2 cat "tagada" > config/mesmails 1.2 a) si le fichier existe, le programme va écrire à la suite des caractères existants (ouverture en write-only) . Dans le cas contraire, il y aura création du fichier. b) dans l'appel à read, la valeur 0 correspond à l'entrée standard c) ce programme lit sur l'entrée standard et recopie les caractères dans un fichier dont le nom est passé en paramètre par l'utilisateur. Si ce fichier existe, les caractères sont recopiés à la suite, sinon, le fichier est créé. Partie 3 -------- 3.1 un programme est un exécutable. Un processus c'est un programme en cours d'exécution. Deux processus peuvent exécuter (en meme temps) deux instances (ou plus) d'un meme programme. 3.2.a) | + Bonjour ! | o | \ | \ | \ | | mesg1 + + mesg1 | | | | mesg3 + + mesg2 | | | | mesg4 + + mesg4 | | | | x x 3.2.b deux exécutions possibles, car rien n'indique qui du père ou du fils n'exécute son code en premier : Bonjour ! message1 message1 message2 message3 message4 message4 ou Bonjour ! message1 message1 message3 message2 message4 message4 NB : il y a bien sur d'autres exécutions possibles. 3.2.c) pour que message 4 ne soit imprimé qu'une seule fois, il faut faire en sorte qu'il soit dans le code d'un des deux processus. Pour assurer qu'il s'affiche à la fin, on va devoir s'assurer qu'un des processus meurt avant. On choisit donc de faire exécuter le printf au père, après avoir attendu la mort du fils : if (valeur == 0) { // fils printf("message 2\n"); sleep(10);// pour tester. } else { printf("message 3\n"); wait(&n); printf("message 4\n"); } EOF