M2 CCI - Programmation et Langages

Stage de Rentrée – Séance 2

 

But de la séance 2


Sauf indication contraire, tous les exercices doivent se faire dans votre répertoire PL1 créé lors de la séance 1.

EXERCICE (en préambule)

  1. copiez dans votre répertoire principal le fichier ~mounlaur/CCI_PL1/Rentree2/Rentree2.tar.gz

  2. Décompressez et de-archivez ce fichier (reportez-vous à la séance précédente si vous avez oublié comment faire)

  3. effacer le fichier Rentree2.tar.gz de votre répertoire principal


Dans la suite les parties écrites en vert peuvent être ignorées en première lecture (et traitées ensuite en fonction du temps disponible).

 1- Premiers pas avec le langage C

L'objectif est ici d'examiner un premier programme C, de le compiler et de l’exécuter, puis de le modifier.
On considère pour cela le programme C suivant, qui est dans votre répertoire Rentree2/max.c

#include <stdio.h>

int main() {
    int x, y ;
   
    printf ("tapez deux entiers au clavier\n") ;
    scanf("%d", &x) ;
    scanf("%d", &y) ;

    if (x > y) {
        printf("le maximum des deux entiers est %d\n", x) ;
    } else {
       
printf("le maximum des deux entiers est %d\n", y) ;
    } ;

    return 0 ;
}

1.1 Compiler et exécuter un programme C

Ce fichier contient ce que l’on appelle un programme source. Il est constitué d’une suite d’instructions du langage C, facile à comprendre par une personne qui connaît ce langage,  mais non exécutable sous cette forme par l'ordinateur. Pour produire un programme exécutable à partir de ce programme source il faut donc d'abord le traduire et produire un nouveau fichier contenant des instructions exécutables par le processeur de la machine (mais plus du tout lisible facilement par un utilisateur!). On utilise pour cela un compilateur.

Pour exécuter une compilation C, nous utiliserons la commande gcc (sous une forme très simple dans cette séance, qui sera détaillée en cours) :

gcc -Wall -o pgm_executable pgm_source



EXERCICE  

  1. Placez-vous dans votre  répertoire Rentree2

  2. Tapez la commande suivante : gcc -Wall -o max max.c 

  3. Observer que le fichier max a été créé dans le répertoire courant (commande : ls) ; vérifiez que ce fichier est bien exécutable (commande ls -l )

  4. Exécuter le programme max, en tapant ./max (le format de cette commande est expliqué dans la suite!)

  5. Peut-on lire avec un éditeur de texte comme gedit le contenu du fichier max ?

  6. Peut-on exécuter le programme source max.c (avec la commande ./max.c ?). Et en lui ajoutant les droits d’exécution avec la commande chmod ?



1.2 Modifier un programme C existant

L’exercice suivant va vous permettre de modifier le programme source max.c ...

EXERCICE

  1. Toujours dans le répertoire Rentree2, copiez le fichier max.c en un fichier min.c

  2. Ouvrez le fichier min.c (avec gedit) et modifiez-le pour que le programme affiche maintenant le minimum des deux entiers

  3. Sauvegardez ce nouveau programme, et compilez-le en un programme exécutable de nom min

  4. Testez votre programme min



Dans la commande de compilation, l'option -Wall permet d'être informé sur l'ensemble des erreurs et avertissements (ou warnings) relevés par le compilateur sur la correction du programme source.  Tant qu'il subsiste des erreurs, le programme exécutable n'est pas produit. Si tous les warning ne sont pas éliminés le programme exécutable est tout de même produit ; mais pour éviter des mauvaises surprises, nous vous conseillons néanmoins de les corriger systématiquement (ils indiquent en général des problèmes potentiels à l'exécution). Si vous ne mentionnez pas l'option -Wall les warnings ne sont pas signalés.

1.3 Utiliser Visual Studio Code (VSC)

Pour programmer plus « confortablement » on peut également utiliser un Environnement de Développement  Intégré (ou IDE, pour Integrated Development Environment) comme Visual Studio CodeTM (ou VSC en abbrégé).

EXERCICE

  1. Dans le menu Applications (en haut à droite de l’écran) ouvrez l’application Visual Studio Code (VSC)

  2. Depuis la fenêtre de VSC, ouvrez le fichier max.c (menu Fichiers → « Ouvrir le Fichier ... »)

  3. Toujours dans VSC ouvrez alors un terminal intégré à VSC (menu Terminal → « Nouveau terminal »)

  4. Dans ce terminal, placez-vous dans le répertoire Rentree2 (avec la commande cd)

  5. Vous pouvez maintenant lancer la compilation et l’exécution du programme max.c depuis le terminal ouvert dans VSC comme cela a été fait précédemment (avec la commande gcc et la commande ./max).



Nous verrons plus tard des utilisations plus avancées de VSC. Notez également que cet outil est disponible sous les environnements Windows ou Mac (et donc le cas échéant sur votre machine personnelle).


2- Manipulation de processus Unix

2.1 Notion de processus

Un processus est un programme qui est en cours d'exécution. A un instant donné, plusieurs processus peuvent s'exécuter sur un même ordinateur. Chaque processus est identifié par un numéro unique dans le système (pid, pour process id) et c'est au travers de cette identification qu'un utilisateur pourra agir sur le processus (l'arrêter, le redémarrer, etc).

2.2 Identification d'un processus

La commande ps permet de connaître les identifications des processus actifs (c.a.d en cours d'exécution) à l'instant courant. Il existe un grand nombre d'options associées à cette commande.  Par exemple,

2. 3 Tâches de fond

Quand vous lancez un programme, vous perdez la main jusqu'à la fin de l'exécution du programme. Vous pouvez vous dégager d'une exécution en demandant que celle-ci soit transformée en tâche de fond. Pour cela, il faut faire suivre l'appel du programme par le symbole &.



EXERCICE  

    a. Toujours dans le répertoire Rentree2, tapez la commande programme nedit max.c & (bien terminée par le symbole &)
    b. Vous pouvez constater que l’éditeur nedit est utilisable et que vous pouvez encore taper des commandes dans le terminal à partir duquel il a été lancé (ces deux processus s’exécutent en parallèle). Par exemple vous pouvez compiler puis exécuter le programme max sans quitter nedit ...
    c. Une fois ces opérations effectuées vous pouvez fermer nedit.



3- Manipulation des commandes données au shell   

3.1 Historique
Le shell (ou interpréteur de commande) conserve un historique des commandes que vous lui avez données à exécuter.
Pour remonter dans la liste des commandes précédentes, vous pouvez utiliser Ctrl-P ou la flèche montante de votre clavier (Ctrl-N ou flèche descendante pour redescendre).
Pour visualiser l'historique, tapez history.
Pour ré-exécuter une commande donnée, tapez !<numéro de commande>.


3.2 Aliasing [OPTIONNEL]

Certaines commandes peuvent être longues à taper ; Il existe un moyen simple de " raccourcir " les commandes. Le mécanisme d'alias permet en effet de dire à l’interprète de commandes : considère que tel mot signifie telle commande. Par exemple :

alias ll='ls -l'             ll sera automatiquement associé à ls -l
unalias ll                   supprime l'alias
 
 

EXERCICE  

    Testez l'usage de l'historique et des alias:

    1. ré-exécutez la dernière commande ls que vous avez exécutée (sans la re-taper, en utilisant l'historique)

    2. avec la commande alias (sans arguments), consultez la liste des alias prédéfinis

    3. créez vous un alias de nom pere qui  vous fait remonter d'un répertoire dans l'arborescence (remplace le répertoire courant par le répertoire pere)

    4. Exécutez cet alias, puis détruisez-le. Que se passe t-il si vous exécutez maintenant la commande pere ?

    5. Créez un nouvel alias de nom ls qui exécute la commande date. Est-ce cet alias ou la commande ls classique qui est appelée lorsque vous tapez ls ? Détruisez cet alias.

 

4- Variables d'environnement
Lors de la connexion d'un utilisateur dans le système, ce dernier possède un environnement de travail. Comme vous avez pu le remarquer dans les sessions précédentes, cet environnement vous place automatiquement dans votre répertoire principal lors de la connexion. Il y a en fait beaucoup d'autres actions qui sont effectuées de manière implicite lors de cette connexion. Ces actions sont "programmées" dans différents fichiers de configuration, dont l'un s'appelle .cshrc (il s'agit en fait du fichier de configuration du shell csh). Le fichier .cshrc est "exécuté' à chaque lancement du shell (donc à chaque fois qu'un xterm est lancé).

Les actions effectuées dans un fichier de configuration consistent entres autres en :

Le shell est non seulement un langage de commande, mais également un langage de programmation. Pour cette raison, il introduit les notions de variables, de paramètre, de structures de contrôle (si, sinon, tant que, etc).  Certaines variables shell sont appelées variables d'environnement.  Elle sont identifiées par un nom. L'affectation d'une valeur à une variable d'environnement permet de configurer son propre environnement de travail. Par exemple :


4.1 La variable path

On rappelle que la plupart des commandes Unix utilisées (ls, cd, cp, etc.) sont des programmes stockés sur le disque dur de la machine. La variable path est une variable d'environnement importante. Elle contient la liste des répertoires dans lesquels l’interprète de commande va aller chercher (dans cet ordre !) les programmes correspondant aux commandes que vous lui fournissez. La commande which permet de rechercher l'emplacement d'un programme. Lorsque vous tapez which nom_prog, le shell recherche un fichier exécutable de nom nom_prog. Il effectue sa recherche en parcourant  les répertoires définis dans la variable path (comme le ferait l’interprète de commande pour  exécuter mon_prog).
 

EXERCICE   

    a. Rechercher l'emplacement du programme date, qui donne la date courante.  
    b. Créez un répertoire ESSAI et copiez ce programme date dans ce répertoire sous le nom ls
    c. Placez-vous dans  le répertoire ESSAI

    d. Examinez le contenu de votre variable path (echo $path).  Quel programme sera exécuté si vous tapez ls ?
    e. Vérifiez-le en tapant
    ls
    f. Tapez maintenant
    ./ls et interprétez ce qu'il se passe.



6. Redirection des entrées-sorties d'un programme dans un fichier [OPTIONNEL]

Lorsqu'un programme s'exécute, tous ses affichages se font par défaut sur l'écran. Il existe un mécanisme qui permet de rediriger les affichages dans un fichier. Pour cela , il faut faire suivre l'appel du programme par le symbole > suivi du nom de fichier voulu (nom_prog > nom_fichier). Cette possibilité est intéressante lorsque le nombre d'affichage est important, et que l'on souhaite pouvoir vérifier la bonne exécution du programme en étudiant ses traces d'exécution.
Deux variantes utiles :

nom_prog > nom_fichier   crée (ou remplace) le fichier nom_fichier avec la sortie de nom_prog

nom_prog >> nom_fichier ajoute la sortie de nom_prog  à la fin du fichier nom_fichier 

Il est également possible de rediriger les entrées d'un programme, pour que celui-ci lise les données non pas au clavier mais depuis un fichier donné. Pour cela, il faut faire suivre l'appel du programme par le symbole < suivi du nom de fichier d'entrée.

 

EXERCICE  

    a. Redirigez les sorties de la commande ls dans un fichier ls_res.  
    b. Recommencez en ajoutant la nouvelle sortie de la commande ls au même fichier ls_res.   
    c. Que fait la commande suivante : cat ls_res > f
    d.
    Exécuter le programme max en redirigeant ses entrées depuis un fichier. Que faut-il écrire dans ce fichier pour que le programme fonctionne ?

 

7. Redirection de la sortie d'un programme vers l'entrée d'un autre [OPTIONNEL]

Il est possible de rediriger les sorties d'un programme de telle sorte que les données produites en sortie soient fournies en entrée à un deuxième programme, activé à la suite du premier programme.

 

EXERCICE 

Que fait la commande suivante : ls -l | wc -l      (utilisez man pour comprendre ce que fait wc).

 

8. Séquencement

L'opérateur de séquencement est le point virgule. Il permet d'exécuter plusieurs commandes en séquence.

Cde1 ; Cde2 ; Cde3 engendre l'exécution de Cde1, puis de Cde2, puis de Cde3.

EXERCICE 

Construire la commande composée de trois sous-commandes séquentielles, qui effectue l'équivalent de la commande donnée à l'exercice précédent en passant par un fichier intermédiaire :  

  1. le résultat de ls -l est placé dans un fichier f

  2. on comptabilise le nombre de lignes de f

  3. on détruit f



  9. Fichier de commande

Lorsqu'une suite de commande est souvent utilisée il est possible de la mémoriser dans un fichier de commande. En tapant le nom de ce fichier l’interpréteur exécutera alors chacune de ces commandes (ce qui nous évite de toutes les saisir à chaque fois). On donne ci-dessous un exemple de fichier de commande :

#!/bin/sh

cd

echo "le repertoire courant est"
pwd
cd PL1
mkdir TP1
cd TP1
echo "le repertoire courant est"
pwd


EXERCICE 

  1. Saisissez ces commandes dans un fichier de nom makeTP1.sh

  2. Exécutez la commande ./makeTP1.sh

  3. Donnez-vous les droits en exécution sur le fichier makeTP1.sh

  4. Exécutez la commande ./makeTP1.sh

  5. Examinez le fichier de commande exemple.sh dans votre répertoire Rentree2

  6. Exécutez les commandes suivantes :

    • ./exemple.sh

    • ./exemple.sh 42

    • ./exemple.sh septembre 2012

    • ./exemple.sh ab cd

  7. En vous inspirant de cet exemple, modifier makeTP1.sh en un fichier de commande makeTP.sh qui prend en paramètre le numéro du répertoire TP à créer.


  10. Exercice de synthèse

Écrire un fichier de commande qui prend deux fichiers en paramètres et affiche le nombre de ligne de celui qui en contient le plus ...