TP6 – Programmes exécutables

Introduction

L'arborescence d'un système d'exploitation contient des fichiers particuliers appelés programmes exécutables. Ces exécutables ont pour vocation d'être exécutés par le processeur central de l'ordinateur (CPU) pour modifier son état interne (contenu de la mémoire) ou agir sur ses périphériques (afficher un message à l'écran, accéder à des données sur le disque, envoyer une information sur le réseau, etc).

Les fichiers exécutables contiennent un programme informatique pouvant être stockés sous deux formes :

  • sous forme textuelle. Le code exécutable est le code source du programme écrit dans un langage informatique, compréhensible par un programmeur. Son exécution nécessite un interpréteur, un autre programme qui va exécuter le programme source, instruction par instruction. On dit que de tels programmes sont des programmes interprétés. On les appelle aussi des scripts, comme ceux que vous avez écrits dans les TPs précédents.
  • sous forme binaire. Les instructions à exécuter sont ici stockées sous forme numérique, en codage binaire. Cette suite de 0 et de 1 est un langage machine qui est le langage natif du processeur, c'est à dire le seul langage que le processeur puisse traiter directement. Ces fichiers exécutables ne sont plus compréhensibles par un programmeur, le langage source initial a été traduit par un compilateur. On dit que de tels programmes sont des programmes compilés.

Pour un système d'exploitation, un exécutable est un fichier qui a reçu le droit d'exécution, au sens des permissions accordées aux fichiers (lecture, écriture et exécution). Il s'agit par exemple des commandes accessibles dans un terminal.

Expérimentez

Vérifiez que les commandes que vous avez maintenant l'habitude d'appeler dans le terminal ont bien le droit en exécution.

L'emplacement du fichier de la commande dans l'arborescence peut être déterminée par la commande which.

La commande file précise le format d'un exécutable : langage machine ou langage de programmation.

Par exemple avec la commande cp :

 # emplacement de cp :
 which cp
 /bin/cp
 # permissions de cp (x : exécution)
 ls -l /bin/cp
 -rwxr-xr-x 1 root root 130304 janv. 14  2015 /bin/cp
 # format de l'exécutable
 file /bin/cp
 /bin/cp: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=ad985d5fbb3036a578c8e7f61a2d8756f373d448, stripped
 # ELF 64-bit indique que le fichier est stocké en langage machine.
 # Il n'est pas lisible par un humain :
 head /bin/cp
 # la commande head affiche les premières ligne d'un fichier
  • Essayez avec d'autres commandes.
  • Déterminez le format des commandes tzselect et firefox.
    (un « symbolic link » est un lien – ou raccourci – vers un autre fichier)

Chemin vers un exécutable

Un exécutable n'est donc rien d'autre qu'un fichier stocké dans l'arborescence de fichiers et dont les droits d'exécution ont été donnés. Comme tout fichier il est nécessaire de connaître son emplacement dans l'arborescence pour l'invoquer. Par exemple : /bin/ls appelle la commande ls.

Or vous remarquerez que les commandes sont appelables sans préciser leur chemin. Cela est rendu possible par le système d'exploitation pour le confort d'utilisation en précisant dans une variable d'environnement tous les emplacements dans lesquels des exécutables sont susceptibles d'être appelés.

Cette variable s'appelle PATH et vous pouvez en voir le contenu ainsi :

printenv PATH
/bin:/usr/bin:/usr/local/bin

Il s'agit d'une liste de chemins séparés par le caractère ' :'.

Expérimentez

Nous allons vérifier le rôle de la variable PATH dans l'accès aux exécutables du système d'exploitation.

  1. Commençons par effacer les chemins que contient PATH :
    export PATH=""
  2. Vérifiez maintenant que vous ne pouvez plus exécuter directement les commandes :
     ls
     bash: ls: Aucun fichier ou dossier de ce type
  3. Mais elles sont toujours accessibles en précisant leur chemin :
    /bin/ls
  4. Nous allons reconstruire la variable PATH en insérant le chemin /bin :
    export PATH="/bin"
  5. Testez si la commande ls est à nouveau disponible
  6. Constatons que le chemin a bien été ajouté :
     printenv PATH
     printenv : commande introuvable
  7. En effet printenv ne se trouve pas dans /bin mais dans /usr/bin :
    /usr/bin/printenv PATH
  8. Ajoutons le chemin vers le commande printenv :
    export PATH=${PATH}:/usr/bin
    La commande précédente ajoute /usr/bin au contenu courant de la variable PATH et on le stocke à nouveau dans PATH.
  9. Nous pouvons donc directement afficher le contenu de PATH avec printenv :
     printenv PATH
     /bin:/usr/bin

Nous pouvons continuer à ajouter d'autres chemins à la variable PATH pour invoquer des exécutables qui s'y trouveraient.

Création d'exécutables

Pour illustrer la notion de fichiers exécutables, nous allons créer deux programmes qui pourront être exécuté dans un terminal. Un sous forme textuelle (programme interprété), l'autre sous forme binaire (programme compilé).

Programme interprété

Nous ne pouvons pas passer à côté du fameux « Hello Word », le programme de référence des débutants !

D'abord avec le langage de script bash. Dans un dossier TP6, recopiez dans un fichier hello.sh :

 #!/bin/bash
 echo "Hello, World!"

Vous pouvez l'exécuter en invoquant l'interpréteur bash pour ce script :

 bash hello.sh

Vous pouvez aussi le rendre exécutable en lui fournissant les permissions adéquates :

chmod +x hello.sh

Il peut alors être appelé directement en précisant son chemin d'accès car le répertoire courant ne se trouve pas référencé dans la variable d'environnement PATH :

./hello.sh

Maintenant avec le langage Python, un autre langage interprété. Créez un fichier hello.py :

 #! /usr/bin/python
 print "Hello World!"

On peut l'exécuter avec son interpréteur :

python hello.py

Exécutez-le maintenant directement après lui avoir donné les droits d'exécution.

Programme compilé

Avec le langage C. Créez un fichier hello.c :

 /* Hello World program */
 #include <stdio.h>
 int main() {
   printf("Hello World \n");
   return 0; /* code retour : tout s'est bien passé */
 }

Compilation et création de la commande hello :

gcc -o hello hello.c

gcc est le compilateur et l'option -o indique le nom de l'exécutable qui doit être généré.

Vérifiez que la compilation a bien créé un programme exécutable en format binaire.

Exécutez ce programme.

Intégration d'un exécutable dans le gestionnaire de bureau

Nous avons vu la variable d'environnement PATH qui permet d'invoquer un programme dans un terminal sans préciser son chemin. Il existe un mécanisme similaire au niveau du gestionnaire de bureau Unity d'Ubuntu. Il s'agit de fichiers de configuration d'extension .desktop qui accompagnent les programmes exécutables pour préciser leur emplacement, un nom et éventuellement une icône. Cette méthode de faire résulte d'un effort de standardisation mutualisé entre plusieurs gestionnaires de bureau (Unity, Gnome, KDE).

L'objectif de cette partie est de créer de tels fichiers de configuration en partant d'une version minimale.

Les fichiers de configuration fournis par le gestionnaire de bureau sont rassemblés dans le dossier /usr/share/applications/ (allez voir le nombre d'applications disponibles). Ils servent à trouver une application via l'interface graphique.

Les fichiers .desktop sont des fichiers texte dans lesquels trois mots clés doivent être renseignés au minimum :

  • Type  : soit Application, Link ou Directory ;
  • Name  : Nom du programme tel qu'il apparaitra dans dans l'interface graphique ;
  • Exec  : nom de l'exécutable accessible par la variable PATH ou chemin complet.
Expérimentez

Appuyez sur la touche Super (entre ctrl et alt) et cherchez le programme gedit. Le système le trouve car il existe un fichier org.gnome.gedit.desktop dans le dossier /usr/share/applications/.

  1. vérifiez que ce fichier existe
  2. et éditez-le pour en visionner le contenu :
    gedit /usr/share/applications/org.gnome.gedit.desktop &
  3. retrouvez les trois clés minimales ( Type, Name et Exec)

Nous allons voir maintenant comment créer nos propres fichiers .desktop pour accéder à des exécutables par l'interface graphique.

Programme Xeyes

capture d'écran xeyes

Cette application affiche des yeux qui suivent le curseur à l'écran. Elle est inutile donc indispensable !

On la lance dans le terminal par xeyes.

Vous pouvez faire un clic_droit sur la barre de titre et sélectionner « Toujours au premier plan » pour qu'aucune fenêtre ne puisse la recouvrir.

Vous pouvez vérifier que la recherche de xeyes par l'interface graphique (touche Super) n'aboutit pas. Cela s'explique par l'absence d'un fichier .desktop pour ce programme. Nous allons donc en créer un.

Création d'un fichier xeyes.desktop

N'ayant pas la permission d'écrire dans le dossier /usr/share/applications, il est prévu un autre emplacement pour stocker les fichiers de configuration de chaque utilisateur. Il s'agit du dossier ~/.local/share/applications/.

Expérimentez
  1. Créez ce dossier s'il n'existe pas.
  2. Sauvegardez-y un fichier xeyes.desktop dont voici le contenu :
     [Desktop Entry]
     Version=1.0
     Type=Application
     Name=Yeux
     Exec=xeyes
     Comment=Les gros yeux qui suivent le pointeur de souris
  3. Si tout est correct, vous pouvez maintenant trouver le programme par l'interface graphique par la touche Super et en tapant « Yeux » ou « xeyes ».

Ajouter une icône

Il est possible d'ajouter des clés supplémentaires dans le fichier xeyes.desktop. On peut par exemple ajouter une icône pour ce programme.

Expérimentez
  1. Nous allons utiliser dans un premier temps une icône disponible dans les dossiers système : face-surprise-symbolic.svg qui se trouve ici : /usr/share/icons/Adwaita/scalable/emotes/.
  2. Vous pouvez visionner toutes les icônes disponibles en vous plaçant dans ce dossier avec le gestionnaire de fichiers ( nautilus /usr/share/icons/Adwaita/scalable/emotes/ dans un terminal, ou touche Super puis fichiers et déplacez-vous dans le dossier).
  3. Trouvez face-surprise-symbolic.svg dans la liste.
  4. Vous pouvez associez cette icône avec le programme xeyes en ajoutant cette ligne dans le fichier xeyes.desktop :
    Icon=face-surprise-symbolic.svg
  5. Vérifiez que l'icône est bien prise en compte en recherchant le programme avec l'interface graphique.

Utiliser sa propre icône

Il est possible d'utiliser une icône personnalisée stockée dans un dossier sous sa racine personnelle.

Expérimentez
  1. Créez le dossier : ~/.local/share/icons/perso/
  2. Avec le navigateur Web aller à l'adresse https://commons.wikimedia.org/wiki/File:Xeyes.png
  3. Sauvez l'image (clic-droit > Enregistrer l'image sous...) dans le dossier ci-dessus avec le nom xeyes_perso.png
  4. Modifiez le fichier xeyes.desktop pour y mettre à jour la clé Icon :
    Icon=/chemin/absolu/vers/xeyes_perso.png
  5. Vérifiez que la nouvelle icône est bien prise en compte.

Application dans un terminal

Il est possible de créer un fichier de configuration .desktop pour un programme s'exécutant dans un terminal. Pour cela il suffit d'ajouter une clé « Terminal=true ».

Nous allons l'illustrer avec la commande top qui affiche les programmes en cours de fonctionnement.

Expérimentez
  1. Lancez d'abord la commande top dans un terminal.
  2. Quittez-la en tapant la touche ' q'
  3. Sauvegardez au bon emplacement un fichier top.desktop contenant les lignes suivantes :
     [Desktop Entry]
     Version=1.0
     Type=Application
     Name=Top
     Exec=top
     Icon=gnome-terminal
     Comment=display top CPU processes
     Comment[fr]=affiche l'activité des processus
     Terminal=true
  4. Vérifiez que le programme top se trouve bien par l'interface graphique.