#!/bin/bash
# Ceci est un commentaire (ignoré par l'interpréteur)
echo "Bonjour, quel est votre nom ?"
read nom # Lit l'entrée de l'utilisateur et la stocke dans la variable "nom"
echo "Ravi de vous rencontrer, $nom !"
| Retrouvez en vidéo l’introduction à Linux et ses commandes, ainsi que des exercices pour vous entraîner ! |
Ce document vous guidera à travers les concepts fondamentaux de scripts, programmes, binaires (statiques et dynamiques), bibliothèques et modules.
Imaginez que vous écrivez une recette de cuisine. Cette recette, c’est votre code source. C’est une série d’instructions écrites dans un langage que l’ordinateur (ou plutôt, un programme spécial) peut comprendre. Mais l’ordinateur ne peut pas exécuter directement la recette telle quelle. Il faut la "traduire" en instructions qu’il comprend, un peu comme traduire la recette du français vers l’anglais. Ce processus s’appelle la compilation (pour certains langages) ou l'interprétation (pour d’autres).
Qu’est-ce qu’un script ? Un script est une série de commandes écrites dans un langage de script (comme Bash, Python, Perl, Ruby, JavaScript, …). Les scripts sont interprétés, ce qui signifie qu’un programme spécial, appelé interpréteur, lit le script ligne par ligne et exécute les commandes au fur et à mesure.
Analogies :
Recette de cuisine (interprétée) : Vous lisez la recette étape par étape, et vous exécutez chaque instruction au fur et à mesure. Vous n’avez pas besoin de "traduire" toute la recette avant de commencer.
Scénario de film : L’acteur lit le script et joue les scènes au fur et à mesure.
Caractéristiques des scripts :
Interprétés : Exécutés ligne par ligne par un interpréteur.
Faciles à modifier : Vous pouvez modifier le script directement et le réexécuter immédiatement.
Portables (souvent) : Si l’interpréteur est disponible sur un autre système, le script fonctionnera généralement sans modification.
Plus lents (généralement) : L’interprétation à la volée prend plus de temps que l’exécution d’un programme compilé.
Exemples (Bash) :
#!/bin/bash
# Ceci est un commentaire (ignoré par l'interpréteur)
echo "Bonjour, quel est votre nom ?"
read nom # Lit l'entrée de l'utilisateur et la stocke dans la variable "nom"
echo "Ravi de vous rencontrer, $nom !"
#!/bin/bash: Cette ligne (appelée "shebang") indique à l’ordinateur quel interpréteur utiliser (ici, Bash). C’est le chemin vers l’exécutable de l’interpreteur.
Enregistrez ce script dans un fichier (par exemple, bonjour.sh), puis rendez-le exécutable avec chmod +x bonjour.sh, et exécutez-le avec ./bonjour.sh.
Exemples (Python) :
#!/usr/bin/env python3
# Ceci est un commentaire
nom = input("Bonjour, quel est votre nom ? ")
print(f"Ravi de vous rencontrer, {nom} !")
Enregistrez ce script (par exemple, bonjour.py) et exécutez-le avec python3 bonjour.py (vous n’avez pas besoin de chmod +x sur certains systèmes, mais c’est une bonne pratique). Le #!/usr/bin/env python3 permet au système de trouver l’interpréteur Python correct, même s’il est installé à un emplacement différent.
Qu’est-ce qu’un programme ? Un programme est un ensemble d’instructions écrites dans un langage de programmation (comme C, C++, Java, Go, Rust) qui sont compilées en code machine (ou bytecode dans certains cas, comme Java). Le code machine est directement compréhensible par le processeur de l’ordinateur.
Analogies :
Recette de cuisine (compilée) : Vous traduisez toute la recette dans une langue que vous comprenez parfaitement (le code machine) avant de commencer à cuisiner.
Manuel d’instructions d’assemblage de meuble : Le manuel est traduit dans votre langue maternelle avant que vous ne commenciez l’assemblage.
Caractéristiques des programmes (compilés) :
Compilés : Traduits en code machine (ou bytecode) avant l’exécution.
Rapides : L’exécution est généralement plus rapide que celle des scripts, car il n’y a pas d’interprétation à la volée.
Moins portables (généralement) : Le code machine est spécifique à une architecture de processeur et à un système d’exploitation. Un programme compilé pour Linux sur un processeur x86 ne fonctionnera pas directement sur Windows ou sur un processeur ARM.
Compilation: La compilation transforme le code source en code exécutable par la machine, rendant le programme plus rapide mais moins portable.
Exemple © :
#include <stdio.h>
int main() {
printf("Bonjour le monde !\n");
return 0;
}
Pour compiler ce programme (par exemple, bonjour.c) :
gcc bonjour.c -o bonjour # Crée un exécutable nommé "bonjour"
./bonjour # Exécute le programme
Exemple (Java)
public class Bonjour {
public static void main(String[] args) {
System.out.println("Bonjour le monde !");
}
}
Pour compiler (.java vers .class):
javac Bonjour.java
Pour exécuter:
java Bonjour
Java compile en bytecode, qui est ensuite exécuté par la Java Virtual Machine (JVM). La JVM est un interpréteur, mais le bytecode est plus proche du code machine que le code source Java, ce qui rend l’exécution plus rapide qu’un script purement interprété. C’est un exemple de compilation "juste à temps" (JIT).
Qu’est-ce qu’un binaire ? Un binaire (ou fichier binaire) est un fichier qui contient du code machine (ou du bytecode, ou d’autres données non textuelles). Les programmes compilés produisent des fichiers binaires exécutables. Les images, les vidéos, les fichiers audio, etc., sont également des fichiers binaires, mais ils ne sont pas exécutables.
Binaire statique vs. Binaire dynamique :
Binaire statique : Contient tout le code nécessaire à son exécution, y compris les fonctions des bibliothèques qu’il utilise. Il est autonome et n’a pas besoin d’autres fichiers (bibliothèques) pour fonctionner.
Avantages :
Portabilité (limitée) : Fonctionne sur des systèmes où les bibliothèques requises ne sont pas installées (tant que l’architecture du processeur et le système d’exploitation sont compatibles).
Déploiement facile : Un seul fichier à copier.
Inconvénients :
Taille : Les binaires statiques sont plus gros, car ils contiennent tout le code nécessaire.
Mises à jour : Si une bibliothèque utilisée est mise à jour (pour corriger un bug ou une faille de sécurité), il faut recompiler tout le programme pour bénéficier de la mise à jour.
Binaire dynamique : Ne contient pas tout le code nécessaire à son exécution. Il fait appel à des bibliothèques partagées (voir ci-dessous) qui sont chargées au moment de l’exécution.
Avantages :
Taille : Les binaires dynamiques sont plus petits, car ils ne contiennent pas le code des bibliothèques.
Mises à jour : Si une bibliothèque partagée est mise à jour, tous les programmes qui l’utilisent en bénéficient automatiquement (sans recompilation).
Partage de code : Plusieurs programmes peuvent utiliser la même bibliothèque partagée en mémoire, ce qui économise de la mémoire.
Inconvénients :
Dépendances : Le programme a besoin que les bibliothèques requises soient installées sur le système. Si une bibliothèque est manquante ou incompatible, le programme ne fonctionnera pas. C’est ce qu’on appelle "l’enfer des dépendances".
Déploiement plus complexe: Il faut s’assurer que les bonnes versions des librairies sont présentes.
Comment savoir si un binaire est statique ou dynamique (sous Linux) ?
Utilisez la commande ldd:
ldd /bin/ls # Affiche les bibliothèques partagées dont dépend la commande "ls" (dynamique).
ldd /path/to/static_binary # Si le binaire est statique, ldd affichera "not a dynamic executable" (ou un message similaire).
Qu’est-ce qu’une bibliothèque ? Une bibliothèque est un ensemble de fonctions (et de données) pré-écrites que d’autres programmes peuvent utiliser. Elles permettent d’éviter de réécrire le même code encore et encore.
Analogies :
Boîte à outils : Une bibliothèque, c’est comme une boîte à outils avec des tournevis, des marteaux, etc., que vous pouvez utiliser pour différents projets.
Recettes pré-préparées : Au lieu de faire une sauce à partir de zéro à chaque fois, vous utilisez une sauce en pot (la bibliothèque).
Types de bibliothèques :
Bibliothèques statiques : Le code de la bibliothèque est copié dans le programme au moment de la compilation. Cela crée un binaire statique. (Extensions courantes : .a sous Linux, .lib sous Windows).
Bibliothèques partagées (ou dynamiques) : Le code de la bibliothèque n’est pas copié dans le programme. Le programme fait appel à la bibliothèque au moment de l’exécution. (Extensions courantes : .so sous Linux, .dll sous Windows, .dylib sous macOS).
Exemples de bibliothèques :
libc (glibc sous Linux) : La bibliothèque C standard, qui contient des fonctions de base comme printf, scanf, malloc, etc. Presque tous les programmes C l’utilisent.
libm : Bibliothèque mathématique (fonctions comme sin, cos, sqrt, etc.).
libssl, libcrypto : Bibliothèques pour la cryptographie (SSL/TLS).
libcurl : Bibliothèque pour transférer des données avec des URL (utilisée par curl).
Attention : les modules utilisés dans les codes informartiques ne sont pas la même notion que l’outil d’accès à des programmes nommé module.
|
Qu’est-ce qu’un module ? Un module est une unité d’organisation du code. Il regroupe des fonctions, des classes et des variables liées entre elles. C’est une manière de structurer et de réutiliser le code.
En Python: Un module est un fichier .py
En Java: Un module peut être un ensemble de classes dans un package
En C/C++: On parle plutôt de fichiers d’en-tête (.h) et de fichiers source (.c, .cpp)
Analogies:
Chapitres d’un livre: Un module, c’est comme un chapitre d’un livre, qui traite d’un sujet spécifique.
Tiroirs de rangement: Chaque module peut contenir des éléments spécifiques, comme un tiroir pour les chaussettes et un autre pour les T-shirts.
Pourquoi utiliser des modules?
Organisation: Cela rend le code plus facile à comprendre et à maintenir.
Réutilisation: On peut utiliser le même module dans différents programmes.
Éviter les conflits de noms: Si deux modules ont une fonction avec le même nom, il n’y a pas de conflit si vous précisez de quel module vient la fonction.
Exemple (Python):
# Fichier: mon_module.py
def dire_bonjour(nom):
print(f"Bonjour, {nom} !")
def dire_aurevoir(nom):
print(f"Au revoir, {nom} !")
PI = 3.14159
# Fichier: mon_programme.py
import mon_module # Importe le module
mon_module.dire_bonjour("Alice")
print(mon_module.PI)
from mon_module import dire_aurevoir # Importe une fonction spécifique
dire_aurevoir("Bob")
Script = Série de commandes dans un langage de script, exécutées par un interpréteur.
Programme = Ensemble d’instructions dans un langage de programmation, compilées en code machine (ou bytecode).
Binaire = Fichier contenant du code machine (ou bytecode, ou d’autres données non textuelles). Résultat de la compilation d’un programme. * Binaire statique = Contient tout le code nécessaire à son exécution. * Binaire dynamique = Fait appel à des bibliothèques partagées au moment de l’exécution.
*Bibliothèque = Ensemble de fonctions (et de données) pré-écrites que d’autres programmes peuvent utiliser.
*Module = Unité d’organisation du code. Regroupe des fonctions, classes et variables liées.