├── tp-02-04-find
├── fichiers
│ ├── vide.txt
│ ├── ancien.log
│ ├── secret.txt
│ ├── rapport1.txt
│ ├── rapport2.TXT
│ └── script.sh
├── challenge
│ ├── tests
│ │ └── test_arborescence.py
│ └── README.md
└── README.md
├── tp-06-acl
├── challenge
│ ├── document1.txt
│ ├── document2.txt
│ ├── README.md
│ └── tests
│ │ └── test_tp.py
├── fichiers
│ ├── partage
│ │ ├── nouveau_fichier.txt
│ │ └── readme.txt
│ ├── document1.txt
│ ├── document2.txt
│ ├── document3.txt
│ └── document4.txt
└── README.md
├── requirements.txt
├── tp-01-navigation-fichiers
├── fichier_exercice4.txt
├── fichier_exercice1.txt
├── fichier_exercice5.txt
├── fichier_exercice2.txt
├── fichier_exercice3.txt
├── challenge
│ ├── tests
│ │ └── test_tp.py
│ └── README.md
└── README.md
├── .github
└── FUNDING.yml
├── tp-02-01-xargs
├── fichiers
│ ├── exemples1.txt
│ ├── exemples2.txt
│ ├── liste_fichiers.txt
│ └── fichiers_avec_espaces.txt
├── challenge
│ ├── tests
│ │ └── test_xargs.py
│ └── README.md
└── README.md
├── tp-03-premiers-scripts-shell
├── challenge
│ ├── majeurs.txt
│ ├── utilisateurs.csv
│ ├── tests
│ │ └── test_tp.py
│ └── README.md
└── README.md
├── tp-02-00-commandes-avancees
├── fichiers
│ ├── exercice3a.txt
│ ├── exercice5a.txt
│ ├── exercice3b.txt
│ ├── exercice5b.txt
│ └── exercice5.txt
├── challenge
│ ├── utilisateurs.csv
│ ├── tests
│ │ └── test_tp.py
│ └── README.md
└── README.md
├── tp-02-02-sed
├── modifs.sed
├── fichiers
│ ├── serveur.conf
│ ├── users.txt
│ ├── report.csv
│ ├── apache.conf
│ └── logs.txt
└── README.md
├── tp-02-03-awk
├── fichiers
│ ├── ventes.csv
│ ├── passwd.txt
│ ├── utilisateurs.csv
│ ├── logs.txt
│ └── fichiers.txt
├── challenge
│ ├── ventes.csv
│ ├── tests
│ │ └── test_tp.py
│ └── README.md
└── README.md
├── install.sh
├── tp-05-gestion-processus
├── fichiers
│ └── processus.sh
└── README.md
├── cloud-config.yaml
├── tp-07-01-paquets-apt
├── challenge
│ ├── tests
│ │ └── test_tp.py
│ └── README.md
└── README.md
├── contributing.md
├── tp-07-02-paquets-dnf
└── README.md
├── .gitignore
└── README.md
/tp-02-04-find/fichiers/vide.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tp-06-acl/challenge/document1.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tp-06-acl/challenge/document2.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest
2 | pytest-testinfra
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/fichier_exercice4.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tp-02-04-find/fichiers/ancien.log:
--------------------------------------------------------------------------------
1 | Ancien log
2 |
--------------------------------------------------------------------------------
/tp-02-04-find/fichiers/secret.txt:
--------------------------------------------------------------------------------
1 | Top secret
2 |
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/partage/nouveau_fichier.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: stephanerobert89902
2 |
--------------------------------------------------------------------------------
/tp-02-04-find/fichiers/rapport1.txt:
--------------------------------------------------------------------------------
1 | Contenu du rapport1
2 |
--------------------------------------------------------------------------------
/tp-02-04-find/fichiers/rapport2.TXT:
--------------------------------------------------------------------------------
1 | Contenu du rapport2
2 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/fichiers/exemples1.txt:
--------------------------------------------------------------------------------
1 | Ceci est le fichier exemples1.txt.
2 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/fichiers/exemples2.txt:
--------------------------------------------------------------------------------
1 | Ceci est le fichier exemples2.txt.
2 |
--------------------------------------------------------------------------------
/tp-02-04-find/fichiers/script.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo 'Script exécuté'
3 |
--------------------------------------------------------------------------------
/tp-03-premiers-scripts-shell/challenge/majeurs.txt:
--------------------------------------------------------------------------------
1 | Alice
2 | Bob
3 | Stephane
4 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/fichiers/exercice3a.txt:
--------------------------------------------------------------------------------
1 | ligne1
2 | ligne2
3 | ligne3
4 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/fichiers/exercice5a.txt:
--------------------------------------------------------------------------------
1 | 1 Alice
2 | 2 Bob
3 | 3 Charlie
4 |
--------------------------------------------------------------------------------
/tp-02-02-sed/modifs.sed:
--------------------------------------------------------------------------------
1 | s/admin/root/g
2 | /^#/d
3 | 1i\# Liste des utilisateurs
4 |
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/document1.txt:
--------------------------------------------------------------------------------
1 | Ceci est le document 1 pour l'exercice sur les ACL.
2 |
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/document2.txt:
--------------------------------------------------------------------------------
1 | Ceci est le document 2 pour l'exercice sur les ACL.
2 |
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/document3.txt:
--------------------------------------------------------------------------------
1 | Ceci est le document 3 pour l'exercice sur les ACL.
2 |
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/document4.txt:
--------------------------------------------------------------------------------
1 | Ceci est le document 4 pour l'exercice sur les ACL.
2 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/fichiers/exercice3b.txt:
--------------------------------------------------------------------------------
1 | ligne1
2 | ligneModifiee
3 | ligne3
4 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/fichiers/exercice5b.txt:
--------------------------------------------------------------------------------
1 | 1 ALICIA
2 | 2 ROBERT
3 | 4 DENIS
4 |
--------------------------------------------------------------------------------
/tp-02-03-awk/fichiers/ventes.csv:
--------------------------------------------------------------------------------
1 | Produit,Montant
2 | Stylo,2.5
3 | Cahier,4.0
4 | Clé USB,9.99
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | pipx install pytest
3 | pipx inject pytest pytest-testinfra
4 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/fichiers/liste_fichiers.txt:
--------------------------------------------------------------------------------
1 | fichiers/exemples1.txt
2 | fichiers/exemples2.txt
3 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/fichiers/exercice5.txt:
--------------------------------------------------------------------------------
1 | nom,age
2 | Alice,30
3 | Bob,25
4 | Charlie,35
5 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/fichiers/fichiers_avec_espaces.txt:
--------------------------------------------------------------------------------
1 | "mon fichier 1.txt"
2 | "un autre fichier 2.txt"
3 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/challenge/utilisateurs.csv:
--------------------------------------------------------------------------------
1 | Alice,30
2 | Bob,25
3 | Charlie,35
4 | Alice,30
5 | Bob,25
--------------------------------------------------------------------------------
/tp-02-02-sed/fichiers/serveur.conf:
--------------------------------------------------------------------------------
1 | ServerName localhost
2 | DocumentRoot /var/www/html
3 | # localhost alias
4 |
--------------------------------------------------------------------------------
/tp-02-02-sed/fichiers/users.txt:
--------------------------------------------------------------------------------
1 | # Liste initiale
2 | admin
3 | user1
4 | # Commentaire
5 | user2
6 | admin
7 |
--------------------------------------------------------------------------------
/tp-03-premiers-scripts-shell/challenge/utilisateurs.csv:
--------------------------------------------------------------------------------
1 | nom,age
2 | Alice,22
3 | Bob,35
4 | Charlie,17
5 | Stephane,57
--------------------------------------------------------------------------------
/tp-06-acl/fichiers/partage/readme.txt:
--------------------------------------------------------------------------------
1 | Répertoire partage : tous les fichiers créés ici auront des ACL par défaut.
2 |
--------------------------------------------------------------------------------
/tp-02-02-sed/fichiers/report.csv:
--------------------------------------------------------------------------------
1 | Date,Utilisateur,Action
2 | 2024-05-01,alice,connexion
3 | 2024-05-01,bob,deconnexion
4 |
--------------------------------------------------------------------------------
/tp-02-03-awk/challenge/ventes.csv:
--------------------------------------------------------------------------------
1 | Produit,Montant
2 | Stylo,2.5
3 | Cahier,4.0
4 | Clé USB,9.99
5 | Clé USB,7.00
6 | Stylo,1.75
7 |
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/fichier_exercice1.txt:
--------------------------------------------------------------------------------
1 | Ce fichier contient une liste de répertoires.
2 | documents
3 | telechargements
4 | musique
5 | images
6 |
--------------------------------------------------------------------------------
/tp-05-gestion-processus/fichiers/processus.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Script qui tourne en tâche de fond avec une boucle infinie
3 | while true; do
4 | sleep 2
5 | done
--------------------------------------------------------------------------------
/tp-02-02-sed/fichiers/apache.conf:
--------------------------------------------------------------------------------
1 |
2 | ServerAdmin webmaster@localhost
3 | DocumentRoot /var/www/html
4 |
5 | OtherConfig On
6 |
--------------------------------------------------------------------------------
/tp-02-03-awk/fichiers/passwd.txt:
--------------------------------------------------------------------------------
1 | root:x:0:0:root:/root:/bin/bash
2 | user1:x:1001:1001:User One:/home/user1:/bin/bash
3 | user2:x:1002:1002:User Two:/home/user2:/bin/bash
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/fichier_exercice5.txt:
--------------------------------------------------------------------------------
1 | Ligne 1
2 | Ligne 2
3 | Ligne 3
4 | Ligne 4
5 | Ligne 5
6 | Ligne 6
7 | Ligne 7
8 | Ligne 8
9 | Ligne 9
10 | Ligne 10
11 |
--------------------------------------------------------------------------------
/tp-02-03-awk/fichiers/utilisateurs.csv:
--------------------------------------------------------------------------------
1 | Nom;Prenom;ID;Email
2 | Durand;Jean;101;j.durand@example.com
3 | Martin;Claire;102;c.martin@example.com
4 | Bernard;Luc;103;l.bernard@example.com
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/fichier_exercice2.txt:
--------------------------------------------------------------------------------
1 | Bonjour et bienvenue dans le monde Linux.
2 | Ce fichier sera utilisé pour des tests de copie.
3 | Merci de ne pas modifier son contenu.
4 |
--------------------------------------------------------------------------------
/tp-02-02-sed/fichiers/logs.txt:
--------------------------------------------------------------------------------
1 |
2 | INFO: Service démarré
3 | DEBUG: Variable x=42
4 | WARNING: Faible espace disque
5 |
6 | DEBUG: Vérification terminée
7 | ERROR: Connexion refusée
8 |
--------------------------------------------------------------------------------
/tp-02-03-awk/fichiers/logs.txt:
--------------------------------------------------------------------------------
1 | 2023-04-01 INFO Démarrage du système
2 | 2023-04-01 ERROR Échec de la connexion
3 | 2023-04-02 INFO Mise à jour appliquée
4 | 2023-04-03 ERROR Disque plein
--------------------------------------------------------------------------------
/tp-02-03-awk/fichiers/fichiers.txt:
--------------------------------------------------------------------------------
1 | -rw-r--r-- 1 alice staff 2048 Apr 29 10:00 rapport.txt
2 | -rw-r--r-- 1 bob staff 1024 Apr 29 11:00 script.sh
3 | -rw-r--r-- 1 claire staff 3072 Apr 29 12:00 notes.md
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/fichier_exercice3.txt:
--------------------------------------------------------------------------------
1 | Ce fichier doit être déplacé.
2 | Il est temporaire et n'a pas de valeur définitive.
3 | Vous pouvez le déplacer vers un nouveau dossier.
4 | Contenu à supprimer.
5 | Ce texte ne devrait plus exister après l'exercice.
6 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/challenge/tests/test_xargs.py:
--------------------------------------------------------------------------------
1 |
2 | import pytest
3 |
4 | def test_txt_files_deleted(host):
5 | result = host.run("find ../fichiers/ -name '*.txt'")
6 | assert result.stdout.strip() == '', "Des fichiers .txt existent encore dans le dossier fichiers/"
7 |
--------------------------------------------------------------------------------
/cloud-config.yaml:
--------------------------------------------------------------------------------
1 | #cloud-config
2 | users:
3 | - name: admin
4 | sudo: ALL=(ALL) NOPASSWD:ALL
5 | groups: sudo
6 | shell: /bin/bash
7 | lock_passwd: true
8 | package_update: true
9 | package_upgrade: true
10 | packages:
11 | - python3-pip
12 | - pipx
13 | - git
14 | - python3-venv
15 | write_files:
16 | - path: /home/admin/.profile
17 | content: |
18 | export PATH=$PATH:/home/admin/.local/bin
19 | append: true
20 | runcmd:
21 | - chown -R admin:admin /home/admin
22 |
--------------------------------------------------------------------------------
/tp-07-01-paquets-apt/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import testinfra
2 |
3 | def test_preferences(host):
4 | preferences = host.file("/etc/apt/preferences.d/nano")
5 | assert preferences.exists
6 | assert preferences.contains("Package: nano")
7 | assert preferences.contains("Pin: version 7.2*")
8 | assert preferences.contains("Pin-Priority: 1001")
9 |
10 | def test_nano_version(host):
11 | nano = host.package("nano")
12 | assert nano.is_installed
13 | assert nano.version.startswith("7.2")
14 |
--------------------------------------------------------------------------------
/tp-02-04-find/challenge/tests/test_arborescence.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 |
4 | def test_commande_existence():
5 | assert os.path.exists("challenge/commande.txt"), "Le fichier commande.txt est manquant"
6 |
7 | def test_log_suppression_and_gz_creation():
8 | original = "fichiers/gros.log"
9 | compressed = "fichiers/gros.log.gz"
10 |
11 | # Préconditions
12 | assert os.path.exists("challenge/commande.txt"), "commande.txt est requis"
13 |
14 | # Vérifications post-exécution
15 | assert not os.path.exists(original), "Le fichier gros.log aurait dû être supprimé"
16 | assert os.path.exists(compressed), "Le fichier gros.log.gz aurait dû être créé"
17 |
--------------------------------------------------------------------------------
/tp-02-03-awk/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | import pytest
4 |
5 | VENTES_CONTENT = """Produit,Montant
6 | Stylo,2.5
7 | Cahier,4.0
8 | Clé USB,9.99
9 | Clé USB,7.00
10 | Stylo,1.75
11 | """
12 |
13 | EXPECTED_OUTPUT = """Clé USB: 9.99
14 | Clé USB: 7.00
15 | Total: 16.99
16 | """
17 |
18 | def test_script_existence():
19 | assert os.path.exists("analyse_ventes.awk"), "Le fichier 'analyse_ventes.awk' est manquant."
20 |
21 | def test_awk_output(tmp_path):
22 | ventes_file = tmp_path / "ventes.csv"
23 | ventes_file.write_text(VENTES_CONTENT)
24 |
25 | result = subprocess.run(
26 | ["awk", "-f", "analyse_ventes.awk", str(ventes_file)],
27 | capture_output=True, text=True
28 | )
29 |
30 | assert result.returncode == 0, f"awk a échoué : {result.stderr}"
31 | assert result.stdout.strip() == EXPECTED_OUTPUT.strip(), "La sortie n'est pas correcte."
32 |
--------------------------------------------------------------------------------
/tp-06-acl/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🎯 Challenge Final – TP ACL Linux
2 |
3 | ## Objectif
4 |
5 | Configurer correctement les ACL sur les fichiers fournis afin de répondre aux critères suivants.
6 |
7 | ## À faire
8 |
9 | 1. Sur le fichier `document1.txt` :
10 | - Donnez au groupe `stagiaires` un accès en lecture seule.
11 |
12 | 2. Sur le fichier `document2.txt` :
13 | - Donnez à l’utilisateur `etudiant` le droit **en écriture uniquement** (sans lecture ni exécution).
14 |
15 | 3. Sur le dossier `partage/` :
16 | - Ajoutez une ACL par défaut pour que tous les fichiers créés ici soient lisibles et modifiables par le groupe `stagiaires`.
17 |
18 | 4. Dans le dossier `partage/` :
19 | - Créez un fichier `document3.txt` et un dossier `dossier1/`.
20 |
21 | ## Instructions
22 |
23 | - Utilisez les commandes `setfacl` et `getfacl` pour configurer les ACL.
24 | - Vérifiez que les droits sont correctement appliqués avec `getfacl`.
25 |
26 | ## Validation
27 |
28 | Ce challenge est validé automatiquement grâce aux tests présents dans le dossier `tests/`.
29 |
30 | Pour lancer la validation :
31 |
32 | ```bash
33 | pytest -v
34 | ````
35 |
36 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🎯 Challenge Final : Maîtriser `xargs`
2 |
3 | **Objectif :** Supprimer tous les fichiers `.txt` présents dans le dossier `../fichiers/` en utilisant `xargs` de manière sécurisée (en tenant compte des espaces dans les noms de fichiers).
4 |
5 | ## Consignes :
6 |
7 | - Utilisez `find` avec `-print0` et `xargs -0` pour traiter les noms avec des espaces.
8 | - Lancez la commande depuis la racine du projet (à côté du dossier `challenge/`).
9 |
10 | ## ✅ Critères de validation
11 |
12 | Le challenge est validé automatiquement si les tests passent avec succès :
13 |
14 | ```bash
15 | pytest -v
16 | ```
17 |
18 | Exemple de sortie :
19 |
20 | ```plaintext
21 | === test session starts ===
22 | platform linux -- Python 3.10.12, pytest-8.3.5, pluggy-1.5.0 -- /home/outscale/.local/share/pipx/venvs/pytest/bin/python
23 | cachedir: .pytest_cache
24 | rootdir: /home/outscale/Projets/linux-training/tp-02-01-xargs/challenge
25 | plugins: testinfra-10.2.2
26 | collected 1 item
27 |
28 | tests/test_xargs.py::test_txt_files_deleted[local] PASSED [100%]
29 |
30 | ==== 1 passed in 0.01s ====```
31 |
--------------------------------------------------------------------------------
/tp-06-acl/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import testinfra
2 |
3 | def test_document1_acl(host):
4 | # Vérifie que le groupe 'stagiaires' a le droit en lecture seule sur document1.txt
5 | cmd = host.run("getfacl document1.txt")
6 | assert "group:stagiaires:r--" in cmd.stdout, "Le groupe 'stagiaires' n'a pas les bons droits sur document1.txt"
7 |
8 | def test_document2_acl(host):
9 | # Vérifie que l'utilisateur 'etudiant' a le droit en écriture uniquement sur document2.txt
10 | cmd = host.run("getfacl document2.txt")
11 | assert "user:etudiant:-w-" in cmd.stdout, "L'utilisateur 'etudiant' n'a pas les bons droits sur document2.txt"
12 |
13 | def test_partage_default_acl(host):
14 | # Vérifie qu'il y a une ACL par défaut pour le groupe 'stagiaires' sur le dossier partage/
15 | cmd = host.run("getfacl -d partage")
16 | assert "group:stagiaires:rw-" in cmd.stdout, "L'ACL par défaut sur le dossier partage/ n'est pas correcte"
17 |
18 | def test_partage_contents(host):
19 | # Vérifie la présence du fichier document3.txt
20 | f = host.file("partage/document3.txt")
21 | assert f.exists, "Le fichier partage/document3.txt est manquant"
22 | # Vérifie la présence du dossier dossier1/
23 | d = host.file("partage/dossier1")
24 | assert d.is_directory, "Le dossier partage/dossier1/ est manquant"
25 |
--------------------------------------------------------------------------------
/tp-02-04-find/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🏁 Challenge final : Nettoyage automatisé avec `find`
2 |
3 | ## 🎯 Objectif
4 |
5 | Vous devez écrire une **commande `find`** qui identifie et supprime certains fichiers dans le répertoire `fichiers/`.
6 |
7 | ## 🛠️ Consignes
8 |
9 | Vous devez créer un fichier nommé `commande.txt` dans le répertoire
10 | `challenge/`. Ce fichier doit contenir une commande `find` qui répond aux
11 | critères suivants :
12 |
13 | 1. **Recherche tous les fichiers `.log` de plus de 1 Mo** dans `fichiers/` ;
14 | 2. **Les compresse automatiquement** ;
15 | 3. **Affiche les chemins des fichiers supprimés** (grâce à `-print`).
16 |
17 | Exemple attendu dans `commande.txt` :
18 |
19 | ```bash
20 | find fichiers/ -type f
21 | ```
22 |
23 | Exécutez la commande pour vérifier qu'elle fonctionne correctement.
24 |
25 | ## ✅ Critères de validation
26 |
27 | Le challenge est validé automatiquement si les tests passent avec succès :
28 |
29 | ```bash
30 | pytest -v
31 | ```
32 |
33 | Exemple de sortie :
34 |
35 | ```plaintext
36 | === test session starts ===
37 | platform linux -- Python 3.9.22, pytest-8.3.5
38 | plugins: testinfra-10.2.2
39 | collected 2 items
40 |
41 | tests/test_arborescence.py::test_commande_existence PASSED [ 50%]
42 | tests/test_arborescence.py::test_commande_find_effect PASSED [100%]
43 |
44 | ==== 2 passed in 0.02s ====
45 | ```
46 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import testinfra
2 |
3 | def test_resultat1_existe_et_non_vide(host):
4 | f = host.file("resultat1.txt")
5 | assert f.exists, "resultat1.txt n'existe pas"
6 | assert f.size > 0, "resultat1.txt est vide"
7 |
8 | def test_resultat2_existe_et_non_vide(host):
9 | f = host.file("resultat2.txt")
10 | assert f.exists, "resultat2.txt n'existe pas"
11 | assert f.size > 0, "resultat2.txt est vide"
12 |
13 | def test_resultat3_existe_et_non_vide(host):
14 | f = host.file("resultat3.txt")
15 | assert f.exists, "resultat3.txt n'existe pas"
16 | assert f.size > 0, "resultat3.txt est vide"
17 |
18 | def test_resultat4_existe_et_non_vide(host):
19 | f = host.file("resultat4.txt")
20 | assert f.exists, "resultat4.txt n'existe pas"
21 | assert f.size > 0, "resultat4.txt est vide"
22 |
23 | def test_resultat5_existe_et_non_vide(host):
24 | f = host.file("resultat5.txt")
25 | assert f.exists, "resultat5.txt n'existe pas"
26 | assert f.size > 0, "resultat5.txt est vide"
27 |
28 | def test_resultat5_contenu(host):
29 | f = host.file("resultat5.txt")
30 | assert f.contains("ALICE,31")
31 | assert f.contains("CHARLIE,35")
32 | assert f.content_string.count("ALICE,31") == 2
33 | assert f.content_string.count("CHARLIE,35") == 1
34 | assert len(f.content_string.strip().splitlines()) == 3
35 |
--------------------------------------------------------------------------------
/tp-03-premiers-scripts-shell/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pytest
3 |
4 | def test_script_existe(host):
5 | script = host.file("analyse_utilisateurs.sh")
6 | assert script.exists, "Le script analyse_utilisateurs.sh n'existe pas."
7 |
8 | def test_script_executable(host):
9 | script = host.file("analyse_utilisateurs.sh")
10 | assert script.mode & 0o111, "Le script analyse_utilisateurs.sh n'est pas exécutable."
11 |
12 | def test_sortie_terminal(host):
13 | cmd = host.run("./analyse_utilisateurs.sh")
14 | assert cmd.rc == 0, "Le script s'est terminé avec une erreur."
15 | assert "Nombre total d'utilisateurs" in cmd.stdout, "Le nombre d'utilisateurs n'est pas affiché."
16 | assert "Âge moyen" in cmd.stdout, "L'âge moyen n'est pas affiché."
17 | assert "Utilisateur le plus âgé" in cmd.stdout, "L'utilisateur le plus âgé n'est pas affiché."
18 |
19 | def test_majeurs_txt(host):
20 | majeurs = host.file("majeurs.txt")
21 | assert majeurs.exists, "Le fichier majeurs.txt n'existe pas."
22 | contenu = majeurs.content_string.strip().splitlines()
23 | assert len(contenu) >= 1, "Le fichier majeurs.txt est vide ou mal rempli."
24 | assert all(nom for nom in contenu), "Certaines lignes de majeurs.txt sont vides."
25 |
26 | def test_utilisateur_plus_age(host):
27 | cmd = host.run("./analyse_utilisateurs.sh")
28 | assert "Stéphane" in cmd.stdout or "Stephane" in cmd.stdout, "L'utilisateur le plus âgé attendu n'est pas affiché."
29 |
--------------------------------------------------------------------------------
/tp-07-01-paquets-apt/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🧩 Challenge : Installation d'une version fixée d'un package
2 |
3 | ## 🎯 Objectif
4 |
5 | Configurer un système Debian pour qu'il utilise un dépôt spécifique et installe
6 | une version précise d'un paquet, en respectant des préférences définies.
7 |
8 | ## 📋 Instructions
9 |
10 | 1. Modifier le fichier `/etc/apt/sources.list` pour ajouter le dépôt suivant :
11 |
12 | ```bash
13 | deb http://deb.debian.org/debian buster main
14 | ```
15 |
16 | 2. Créer ou modifier le fichier `/etc/apt/preferences.d/nano` pour que le paquet `nano`
17 | soit installé en version `7.2-2` avec une priorité de `1001`.
18 |
19 | 3. Mettez à jour la liste des paquets et installez nano.
20 |
21 | ### ✅ Validation
22 |
23 | Exécutez les tests avec la commande suivante :
24 |
25 | ```bash
26 | cd tp-07-paquets-apt
27 | pytest -v challenge/tests/test_tp.py
28 | ```
29 |
30 | Vous devez obtenir un résultat similaire à celui-ci :
31 |
32 | ```bash
33 | pytest -v challenge/tests/test_tp.py
34 | === test session starts ===
35 | platform linux -- Python 3.12.3, pytest-8.3.5, pluggy-1.6.0 -- /home/ubuntu/.local/share/pipx/venvs/pytest/bin/python
36 | cachedir: .pytest_cache
37 | rootdir: /home/ubuntu/linux-training/tp-07-paquets-apt
38 | plugins: testinfra-10.2.2
39 | collected 2 items
40 |
41 | challenge/tests/test_tp.py::test_preferences[local] PASSED [ 50%]
42 | challenge/tests/test_tp.py::test_nano_version[local] PASSED [100%]
43 |
44 | === 2 passed in 0.03s ===
--------------------------------------------------------------------------------
/tp-02-03-awk/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🏁 Challenge final : Traitement de données CSV avec `awk`
2 |
3 | ## 🎯 Objectif
4 |
5 | Vous devez écrire un script `awk` nommé `analyse_ventes.awk` qui lit un fichier
6 | CSV nommé `ventes.csv` (séparé par des virgules) contenant des enregistrements
7 | de ventes sous la forme :
8 |
9 | ```csv
10 | Produit,Montant
11 | Stylo,2.5
12 | Cahier,4.0
13 | Clé USB,9.99
14 | Clé USB,7.00
15 | Stylo,1.75
16 | ```
17 |
18 | Le script devra :
19 |
20 | 1. **Afficher uniquement les lignes contenant le mot "Clé USB"** ;
21 | 2. **Afficher uniquement le montant de ces ventes** ;
22 | 3. **Calculer le total des montants pour "Clé USB"**.
23 |
24 | ## 💡 Format attendu de la sortie
25 |
26 | ```bash
27 | Clé USB: 9.99
28 | Clé USB: 7.00
29 | Total: 16.99
30 | ```
31 |
32 | ## 🛠️ Consignes
33 |
34 | - Le script doit s'appeler `analyse_ventes.awk` ;
35 | - Il doit fonctionner avec la commande suivante :
36 |
37 | ```bash
38 | awk -f analyse_ventes.awk fichiers/ventes.csv
39 | ```
40 |
41 | ## ✅ Critères de validation
42 |
43 | Le challenge est validé automatiquement si les tests passent avec succès :
44 |
45 | ```bash
46 | pytest -v
47 | ```
48 |
49 | Exemple de sortie :
50 |
51 | ```plaintext
52 | === test session starts ====
53 | platform linux -- Python 3.9.22, pytest-8.3.5, pluggy-1.5.0 -- /home/bob/.pyenv/versions/3.9.22/bin/python3.9
54 | cachedir: .pytest_cache
55 | rootdir: /home/bob/Projets/linux-training/tp-04-awk/challenge
56 | plugins: testinfra-10.2.2
57 | collected 2 items
58 |
59 | tests/test_tp.py::test_script_existence PASSED [ 50%]
60 | tests/test_tp.py::test_awk_output PASSED [100%]
61 |
62 | ==== 2 passed in 0.04s =====
63 | ```
64 |
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/challenge/tests/test_tp.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pytest
3 | import testinfra
4 |
5 | def test_arborescence(host):
6 | projet = host.file("projet")
7 | assert projet.is_directory
8 |
9 | docs = host.file("projet/docs")
10 | src = host.file("projet/src")
11 | bin_dir = host.file("projet/bin")
12 | assert docs.is_directory
13 | assert src.is_directory
14 | assert bin_dir.is_directory
15 |
16 | def test_fichiers_contenu(host):
17 | manuel = host.file("projet/docs/manuel.txt")
18 | assert manuel.exists
19 | assert manuel.contains("Documentation du projet")
20 |
21 | main = host.file("projet/src/main.sh")
22 | assert main.exists
23 | assert main.contains('echo "Programme principal"')
24 |
25 | utils = host.file("projet/docs/utils.sh")
26 | assert utils.exists
27 | assert utils.contains('echo "Fonctions utilitaires"')
28 |
29 | script = host.file("projet/bin/script.sh")
30 | assert script.exists
31 | assert script.contains('echo "Programme principal"')
32 |
33 | def test_permissions(host):
34 | main = host.file("projet/src/main.sh")
35 | script = host.file("projet/bin/script.sh")
36 | manuel = host.file("projet/docs/manuel.txt")
37 |
38 | assert main.mode == 0o700
39 | assert script.mode == 0o700
40 | assert manuel.mode & 0o444 == 0o444 # Lisible par tous
41 |
42 | def test_proprietaire(host):
43 | for path in [
44 | "projet",
45 | "projet/docs",
46 | "projet/src",
47 | "projet/bin",
48 | "projet/docs/manuel.txt",
49 | "projet/docs/utils.sh",
50 | "projet/src/main.sh",
51 | "projet/bin/script.sh",
52 | ]:
53 | fichier = host.file(path)
54 | assert fichier.group == "adm"
55 |
56 | def test_find(host):
57 | cmd = host.run("find projet -name '*.sh'")
58 | assert "main.sh" in cmd.stdout
59 | assert "utils.sh" in cmd.stdout
60 | assert "script.sh" in cmd.stdout
61 |
62 |
63 |
--------------------------------------------------------------------------------
/tp-03-premiers-scripts-shell/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🎯 Challenge final : Analyse automatique d’un fichier CSV d’utilisateurs
2 |
3 | ## 📝 Objectif
4 |
5 | Vous devez créer un script **`analyse_utilisateurs.sh`** qui effectue plusieurs
6 | traitements sur un fichier CSV `utilisateurs.csv`. Chaque ligne du fichier est
7 | structurée ainsi :
8 |
9 | ```csv
10 | nom,age
11 | Alice,22
12 | Bob,35
13 | Charlie,17
14 | ```
15 |
16 | ---
17 |
18 | ## ✅ Étapes à implémenter dans le script
19 |
20 | 1. **Vérifier l’existence du fichier `utilisateurs.csv`**. S’il est manquant,
21 | afficher un message d’erreur et quitter avec un code différent de 0.
22 | 2. **Compter le nombre total d’utilisateurs** et l’afficher.
23 | 3. **Calculer et afficher l’âge moyen**.
24 | 4. **Lister les utilisateurs majeurs (âge ≥ 18)** dans un fichier `majeurs.txt`.
25 | 5. **Afficher le nom de l’utilisateur le plus âgé.**
26 |
27 | ---
28 |
29 | ## ⚙️ Contraintes
30 |
31 | - Le script ne doit utiliser **aucune commande externe avancée** comme `awk`,
32 | `jq`, `python`, etc. : utilisez uniquement Bash, `read`, `cut`, `expr`, `if`,
33 | `while`, etc.
34 |
35 | ---
36 |
37 | ## 📦 À rendre
38 |
39 | - Le fichier `resultats.txt` (à créer)
40 | - `majeurs.txt` (généré automatiquement)
41 | - Le fichier `utilisateurs.csv` (sera fourni dans le test)
42 |
43 | ---
44 |
45 | ## ▶️ Lancer les tests
46 |
47 | Depuis le dossier `challenge/` :
48 |
49 | ```bash
50 | pytest -v
51 | ```
52 |
53 | Si tous les tests passent, le challenge est validé.
54 |
55 | ```plaintext
56 | === test session starts ===
57 | platform linux -- Python 3.9.22, pytest-8.3.5, pluggy-1.5.0 -- /home/bob/.pyenv/versions/3.9.22/bin/python3.9
58 | cachedir: .pytest_cache
59 | rootdir: /home/bob/Projets/linux-training/tp-03-premiers-scripts-shell/challenge
60 | plugins: testinfra-10.2.2
61 |
62 | collected 5 items
63 |
64 | tests/test_tp.py::test_script_existe[local] PASSED [ 20%]
65 | tests/test_tp.py::test_script_executable[local] PASSED [ 40%]
66 | tests/test_tp.py::test_sortie_terminal[local] PASSED [ 60%]
67 | tests/test_tp.py::test_majeurs_txt[local] PASSED [ 80%]
68 | tests/test_tp.py::test_utilisateur_plus_age[local] PASSED [100%]
69 |
70 | ==== 5 passed in 0.20s ====
71 | ```
72 |
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🎯 Challenge : Création d'une arborescence avec les commandes Linux de base
2 |
3 | ## Objectif
4 |
5 | Utilisez les commandes Linux de base pour créer l'arborescence suivante :
6 |
7 | ```bash
8 | projet/
9 | ├── docs/
10 | │ └── manuel.txt
11 | ├── src/
12 | │ ├── main.sh
13 | │ └── utils.sh
14 | └── bin/
15 | └── script.sh
16 | ```
17 |
18 | Vous devez créer cette arborescence dans le répertoire `challenge` de ce tP.
19 |
20 | ## Instructions
21 |
22 | 1. Créez le répertoire `projet` avec les sous-répertoires `docs`, `src` et `bin`.
23 | 2. Dans `docs`, créez un fichier `manuel.txt` contenant le texte : `Documentation du projet`.
24 | 3. Dans `src`, créez deux fichiers :
25 | - `main.sh` contenant le texte :
26 |
27 | ```bash
28 | #!/bin/bash
29 | echo "Programme principal"
30 | ```
31 |
32 | - `utils.sh` contenant le texte :
33 |
34 | ```bash
35 | #!/bin/bash
36 | echo "Fonctions utilitaires"
37 | ```
38 |
39 | 4. Copiez `main.sh` dans `bin` sous le nom `script.sh`.
40 | 5. Déplacez `utils.sh` dans `docs`.
41 | 6. Modifiez les permissions :
42 | - `main.sh` et `script.sh` doivent être lisibles et exécutables uniquement par le propriétaire.
43 | - `manuel.txt` doit être lisible par tous.
44 | 7. Changez le propriétaire de tous les fichiers et répertoires en `9001:9001`.
45 | 8. Utilisez `find` pour lister tous les fichiers `.sh` dans le répertoire `projet`.
46 |
47 | ## Validation
48 |
49 | Retourner dans le dossier `challenge` et exécuter le script de validation :
50 |
51 | ```bash
52 | pytest -v test.py
53 | ```
54 |
55 | Si le script de validation passe sans erreur, vous avez réussi le challenge.
56 | Vérifiez les étapes et corrigez les erreurs.
57 |
58 | Tous les tests doivent passer pour valider le challenge.
59 |
60 | ```plaintext
61 | === test session starts ===
62 | platform linux -- Python 3.9.22, pytest-8.3.5, pluggy-1.5.0 -- /home/bob/.pyenv/versions/3.9.22/bin/python3.9
63 | cachedir: .pytest_cache
64 | rootdir: /home/bob/Projets/linux-training/tp-01-navigation-fichiers/challenge
65 | plugins: testinfra-10.2.2
66 | collected 5 items
67 |
68 | tests/test_tp.py::test_arborescence[local] PASSED [ 20%]
69 | tests/test_tp.py::test_fichiers_contenu[local] PASSED [ 40%]
70 | tests/test_tp.py::test_permissions[local] PASSED [ 60%]
71 | tests/test_tp.py::test_proprietaire[local] PASSED [ 80%]
72 | tests/test_tp.py::test_find[local] PASSED [100%]
73 |
74 | === 5 passed in 0.34s ====
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/challenge/README.md:
--------------------------------------------------------------------------------
1 | # 🎯 Challenge final : Analyse de rapports d'utilisateurs
2 |
3 | ## 📝 Objectif
4 |
5 | À l’aide **exclusivement de commandes Linux**, vous devez effectuer une série de
6 | traitements sur un fichier `utilisateurs.csv` fourni.
7 |
8 | 🚫 Aucun script ne doit être écrit.
9 | ✅ Chaque étape doit produire un fichier de résultat nommé `resultat1.txt`,
10 | `resultat2.txt`, ..., `resultat5.txt`.
11 |
12 | ---
13 |
14 | ## ✅ Étapes à effectuer
15 |
16 | 1. **Extraire la colonne des noms** avec `cut` et la convertir en majuscules
17 | avec `tr`.
18 | 🔄 Résultat : `resultat1.txt`
19 |
20 | 2. **Extraire la colonne des âges et remplacer `30` par `31`** avec `cut` +
21 | `sed`.
22 | 🔄 Résultat : `resultat2.txt`
23 |
24 | 3. **Fusionner les deux fichiers précédents** avec `paste` pour obtenir
25 | `NOM,AGE`.
26 | 🔄 Résultat : `resultat3.txt`
27 |
28 | 4. **Filtrer les utilisateurs âgés de plus de 30 ans** avec `awk`.
29 | 🔄 Résultat : `resultat4.txt`
30 |
31 | 5. **Numéroter les lignes filtrées** avec `nl`.
32 | 🔄 Résultat : `resultat5.txt`
33 |
34 | ---
35 |
36 | ## 📦 À rendre
37 |
38 | Les fichiers suivants **doivent exister** :
39 |
40 | - `resultat1.txt`
41 | - `resultat2.txt`
42 | - `resultat3.txt`
43 | - `resultat4.txt`
44 | - `resultat5.txt`
45 |
46 | ---
47 |
48 | ## ▶️ Lancer les tests
49 |
50 | ```bash
51 | pytest -v
52 | ```
53 |
54 | Tous les tests doivent passer pour valider le challenge.
55 |
56 | ```plaintext
57 | === test session starts ===
58 | platform linux -- Python 3.9.22, pytest-8.3.5, pluggy-1.5.0 -- /home/bob/.pyenv/versions/3.9.22/bin/python3.9
59 | cachedir: .pytest_cache
60 | rootdir: /home/bob/Projets/linux-training/tp-02-commandes-avancees/challenge
61 | plugins: testinfra-10.2.2
62 | collected 6 items
63 |
64 | tests/test_tp.py::test_resultat1_existe_et_non_vide[local] PASSED [ 16%]
65 | tests/test_tp.py::test_resultat2_existe_et_non_vide[local] PASSED [ 33%]
66 | tests/test_tp.py::test_resultat3_existe_et_non_vide[local] PASSED [ 50%]
67 | tests/test_tp.py::test_resultat4_existe_et_non_vide[local] PASSED [ 66%]
68 | tests/test_tp.py::test_resultat5_existe_et_non_vide[local] PASSED [ 83%]
69 | tests/test_tp.py::test_resultat5_contenu[local] PASSED [100%]
70 |
71 | === 6 passed in 0.19s ===
72 | ```
73 |
--------------------------------------------------------------------------------
/contributing.md:
--------------------------------------------------------------------------------
1 | # Contribuer au dépôt de formation
2 |
3 | Merci de considérer la possibilité de contribuer à ce dépôt de formation ! En participant, vous contribuez à améliorer la qualité et l'accessibilité du contenu éducatif pour la communauté.
4 |
5 | ## Comment contribuer
6 |
7 | ### Signaler des problèmes
8 |
9 | Si vous rencontrez un problème ou un bug avec le matériel de formation, merci de suivre ces étapes :
10 | 1. **Vérifiez les problèmes existants** : Avant d'ouvrir un nouveau problème, assurez-vous que celui-ci n’a pas déjà été signalé.
11 | 2. **Fournissez des informations détaillées** :
12 | - **Description du problème** : Une explication claire et concise du problème.
13 | - **Étapes pour reproduire** (si applicable).
14 | - **Détails sur l'environnement** (par exemple, OS, version, outils utilisés).
15 | - **Captures d'écran** (si applicable).
16 |
17 | ### Soumettre des modifications
18 |
19 | Nous accueillons toutes les améliorations des matériaux de formation, y compris les corrections de bugs, les mises à jour et les nouvelles fonctionnalités. Merci de suivre ces étapes :
20 |
21 | 1. **Forker le dépôt** : Créez une copie personnelle du dépôt sur GitHub.
22 | 2. **Clonez votre fork** : Clonez le dépôt sur votre machine locale.
23 | ```bash
24 | git clone https://github.com/votre-username/depot-formation.git
25 | ```
26 |
27 | 3. **Créez une nouvelle branche** : Il est préférable de créer une branche distincte pour chaque contribution.
28 |
29 | ```bash
30 | git checkout -b votre-branche
31 | ```
32 | 4. **Apportez vos modifications** : Travaillez sur les mises à jour que vous souhaitez proposer. Assurez-vous de suivre la structure et le formatage des documents existants.
33 | 5. **Rédigez des messages de commit clairs** : Rédigez des messages de commit concis et descriptifs expliquant vos modifications.
34 |
35 | ```bash
36 | git commit -m "Décrivez vos changements"
37 | ```
38 | 6. **Poussez vos modifications** : Poussez la branche vers votre dépôt forké.
39 |
40 | ```bash
41 | git push origin votre-branche
42 | ```
43 | 7. **Créez une pull request** : Rendez-vous sur le dépôt original et créez une pull request. Fournissez une description claire des changements dans la pull request.
44 |
45 | ### Guide de style et de formatage
46 |
47 | * **Formatage Markdown** : Assurez-vous que vos contributions sont correctement formatées en utilisant du Markdown. Merci de vous référer aux fichiers existants pour garantir la cohérence.
48 | * **Exemples de code** : Si vous ajoutez des exemples de code, assurez-vous qu'ils soient bien commentés et respectent les normes de codage pour faciliter leur lecture.
49 | * **Nommage des fichiers** : Suivez les conventions de nommage utilisées dans le dépôt.
50 | * **Tests** : Si cela est applicable, ajoutez des tests pour vos modifications. Vous pouvez les placer dans le répertoire `tests/`.
51 |
52 | ## Notes supplémentaires
53 |
54 | * **Aide à la documentation** : Si vous contribuez à la documentation, assurez-vous que vos modifications soient faciles à suivre et expliquent clairement les concepts pour les apprenants de tous niveaux.
55 | * **Retour sur le matériel de formation** : Si vous avez des suggestions ou des idées pour de nouveaux sujets ou des améliorations, n'hésitez pas à ouvrir un problème !
56 |
57 | Merci pour vos contributions et pour aider à améliorer ces matériaux de formation pour tout le monde !
58 |
--------------------------------------------------------------------------------
/tp-02-02-sed/README.md:
--------------------------------------------------------------------------------
1 | # 🛠️ TP 02-02 : Maîtriser la commande `sed`
2 |
3 | ## Introduction
4 |
5 | Dans ce TP, vous apprendrez à utiliser la commande `sed` pour automatiser des
6 | modifications de texte directement depuis la ligne de commande. Vous découvrirez
7 | comment rechercher, remplacer, supprimer ou insérer des lignes sans ouvrir le
8 | moindre fichier manuellement. La maîtrise de `sed` est un atout pour toute
9 | personne qui gère des fichiers texte (logs, configurations, exports CSV…).
10 |
11 | **Objectif :** savoir modifier rapidement et efficacement du contenu texte avec
12 | `sed`.
13 |
14 | ## Résumé rapide
15 |
16 | * **`sed 's/ancien/nouveau/' fichier`** : remplacer la première occurrence par
17 | ligne.
18 | * **`sed 's/ancien/nouveau/g' fichier`** : remplacer toutes les occurrences.
19 | * **`sed '/motif/d' fichier`** : supprimer les lignes contenant un motif.
20 | * **`sed '3i\\Texte' fichier`** : insérer du texte avant la 3e ligne.
21 | * **`sed '5c\\Nouvelle ligne' fichier`** : remplacer entièrement la 5e ligne.
22 | * **Option `-i`** : modifier le fichier en place.
23 | * **Scripts sed** : regrouper plusieurs commandes dans un fichier et les
24 | appliquer avec `-f`.
25 |
26 | 👉 [Documentation complète ici](https://blog.stephane-robert.info/docs/admin-serveurs/linux/sed/)
27 |
28 | ---
29 |
30 | ## Exercices
31 |
32 | ### 1 Remplacer un mot simple
33 |
34 | **Fichier :** `fichiers/serveur.conf`
35 |
36 | * Remplacez toutes les occurrences de `localhost` par `127.0.0.1`.
37 |
38 | **Commande attendue :**
39 |
40 | ```bash
41 | sed 's/localhost/127.0.0.1/g' fichiers/serveur.conf
42 | ```
43 |
44 | ---
45 |
46 | ### 2 Supprimer des lignes inutiles
47 |
48 | **Fichier :** `fichiers/logs.txt`
49 |
50 | * Supprimez toutes les lignes vides.
51 | * Supprimez toutes les lignes contenant le mot `DEBUG`.
52 |
53 | **Commandes attendues :**
54 |
55 | ```bash
56 | sed '/^$/d' fichiers/logs.txt
57 | sed '/DEBUG/d' fichiers/logs.txt
58 | ```
59 |
60 | ---
61 |
62 | ### 3 Ajouter un entête automatique
63 |
64 | **Fichier :** `fichiers/report.csv`
65 |
66 | * Ajoutez la ligne suivante avant la première ligne :
67 |
68 | `# Rapport généré automatiquement`
69 |
70 | **Commande attendue :**
71 |
72 | ```bash
73 | sed '1i\\# Rapport généré automatiquement' fichiers/report.csv
74 | ```
75 |
76 | ---
77 |
78 | ### 4 Remplacer un bloc entier
79 |
80 | **Fichier :** `fichiers/apache.conf`
81 |
82 | * Remplacez toutes les lignes entre `` et `` par :
83 |
84 | `# Bloc supprimé par sécurité`
85 |
86 | **Commande attendue :**
87 |
88 | ```bash
89 | outscale@dev:~/Projets/linux-training/tp-02-02-sed$ sed '//,/<\/VirtualHost>/c\# Bloc supprimé par sécurité' fichiers/apache.conf
90 | ```
91 |
92 | ---
93 |
94 | ### 5 Utiliser un fichier de script sed
95 |
96 | **Fichier :** `fichiers/users.txt` **Script sed :** `modifs.sed`
97 |
98 | * Le fichier `modifs.sed` contient :
99 |
100 | ```
101 | s/admin/root/g
102 | /^#/d
103 | 1i\\# Liste des utilisateurs
104 | ```
105 | * Appliquez ces modifications sur `users.txt`.
106 |
107 | **Commande attendue :**
108 |
109 | ```bash
110 | sed -f modifs.sed fichiers/users.txt
111 | ```
112 |
113 | ---
114 |
115 | ## 🔥 Challenge à valider
116 |
117 | Rendez-vous dans le dossier [`challenge/`](./challenge/README.md) pour relever
118 | le défi final 🚀 !
119 |
--------------------------------------------------------------------------------
/tp-02-01-xargs/README.md:
--------------------------------------------------------------------------------
1 | # 🛠️ TP 02-01 : Maîtriser la commande `xargs`
2 |
3 | ## Introduction
4 |
5 | La commande `xargs` est un outil incontournable lorsqu'il s'agit de traiter des
6 | listes d'arguments complexes dans un terminal Linux. Elle permet de transformer
7 | une entrée standard (stdin) en arguments pour une autre commande, automatisant
8 | ainsi des tâches répétitives et évitant des erreurs classiques comme *"argument
9 | list too long"*. Elle est fréquemment utilisée avec des commandes comme `find`,
10 | `grep`, ou `rm`.
11 |
12 | ## Résumé de la documentation
13 |
14 | * **Syntaxe de base** :
15 |
16 | ```bash
17 | commande_qui_genere | xargs commande_a_executer
18 | ```
19 |
20 | * **Fonctionnement par défaut** : utilise `echo` si aucune commande n'est
21 | précisée.
22 | * **Options clés** :
23 |
24 | * `-n` : limite le nombre d'arguments par commande.
25 | * `-p` : demande confirmation avant chaque exécution.
26 | * `-I` : remplace un jeton par l'argument dans la commande.
27 | * `-0` : gère les noms de fichiers avec caractères spéciaux (via `find
28 | -print0`).
29 | * `-t` : affiche la commande exécutée (debug).
30 | * **Bonnes pratiques** :
31 |
32 | * Tester avec `echo` avant d'exécuter des commandes destructives.
33 | * Toujours gérer les espaces spéciaux avec `-0`.
34 |
35 | 👉 [Documentation source](https://blog.stephane-robert.info/docs/admin-serveurs/linux/xargs/)
36 |
37 | ## Exercices pratiques
38 |
39 | ### Exercice 1 - Exécuter une commande simple
40 |
41 | **Objectif** : Lister les fichiers mentionnés dans
42 | `fichiers/liste_fichiers.txt`.
43 |
44 | **Commande attendue** :
45 |
46 | ```bash
47 | cat fichiers/liste_fichiers.txt | xargs ls -l
48 | ```
49 |
50 | 💡 *Explication* : `cat` lit le fichier contenant des noms de fichiers, et
51 | `xargs` les passe à `ls -l` pour afficher leurs détails.
52 |
53 | ---
54 |
55 | ### Exercice 2 - Limiter le nombre d'arguments par commande
56 |
57 | **Objectif** : Tester la limitation à 2 fichiers par exécution.
58 |
59 | **Commande attendue** :
60 |
61 | ```bash
62 | echo "un deux trois quatre cinq" | xargs -n 2 echo
63 | ```
64 |
65 | 💡 *Explication* : L'option `-n 2` force `xargs` à exécuter `echo` avec 2
66 | arguments à la fois.
67 |
68 | ---
69 |
70 | ### Exercice 3 - Déplacer des fichiers avec insertion
71 |
72 | **Objectif** : Déplacer les fichiers listés dans `liste_fichiers.txt` vers
73 | `/tmp/` en gardant leur nom.
74 |
75 | **Commande attendue** :
76 |
77 | ```bash
78 | mkdir /tmp/fichiers
79 | cat fichiers/liste_fichiers.txt | xargs -I {} mv {} /tmp/{}
80 | ls /tmp/fichiers
81 | ```
82 |
83 | 💡 *Explication* : `-I {}` remplace `{}` par chaque nom de fichier, pour
84 | personnaliser la commande.
85 |
86 | ---
87 |
88 | ### Exercice 4 - Supprimer des fichiers avec confirmation
89 |
90 | **Objectif** : Supprimer les fichiers listés dans
91 | `fichiers/fichiers_avec_espaces.txt` avec confirmation.
92 |
93 | **Commande attendue** :
94 |
95 | ```bash
96 | cat fichiers/fichiers_avec_espaces.txt | xargs -p rm
97 | ```
98 |
99 | 💡 *Explication* : `-p` vous demande de confirmer avant chaque suppression.
100 |
101 | ---
102 |
103 | ### Exercice 5 - Gérer les noms de fichiers complexes
104 |
105 | **Objectif** : Supprimer les fichiers `.txt` qui peuvent contenir des espaces
106 | dans leur nom.
107 |
108 | **Commande attendue** :
109 |
110 | ```bash
111 | find fichiers/ -name "*.txt" -print0 | xargs -0 rm
112 | ```
113 |
114 | 💡 *Explication* : On utilise `-print0` (séparateur nul) et `-0` pour éviter les
115 | erreurs avec des espaces ou caractères spéciaux.
116 |
117 | ---
118 |
119 | ## 🚩 Challenge à valider
120 |
121 | 👉 Consultez les consignes dans [`challenge/README.md`](./challenge/README.md)
122 | pour le challenge final !
123 |
124 | Bonne pratique 💪 !
125 |
--------------------------------------------------------------------------------
/tp-02-04-find/README.md:
--------------------------------------------------------------------------------
1 | # TP 02-03 : Manipuler les fichiers avec `find`
2 |
3 | ## Introduction
4 |
5 | La commande `find` permet de rechercher efficacement des fichiers et des répertoires sous Linux, en utilisant des critères comme le nom, la taille, la date de modification, les permissions, etc. C’est un outil incontournable pour administrer un système et automatiser des tâches.
6 |
7 | ---
8 |
9 | ## 📚 Résumé de la documentation technique
10 |
11 | - **Nom** : `find`
12 | - **Type** : Commande de recherche
13 | - **Fonctionnalités principales** :
14 | - Recherche par nom (`-name`, `-iname`)
15 | - Filtrage par type (`-type f`, `-type d`, etc.)
16 | - Recherche par taille (`-size`)
17 | - Recherche par date (`-mtime`, `-ctime`, `-atime`)
18 | - Recherche par permissions (`-perm`)
19 | - Recherche par propriétaire (`-user`, `-group`)
20 | - Exécution d’actions (`-exec`)
21 | - **Syntaxe de base** :
22 |
23 | ```bash
24 | find [chemin] [conditions] [actions]
25 | ```
26 |
27 | - `[chemin]` : Répertoire de départ
28 | - `[conditions]` : Critères de sélection
29 | - `[actions]` : Ce qu'on fait sur les résultats
30 |
31 | - **Variables et options utiles** :
32 | - `.` : répertoire courant
33 | - `{}` : représente le fichier courant
34 | - `\;` : fin de la commande après `-exec`
35 |
36 | Plus d'informations sur le [guide dédié à la commande `find`](https://blog.stephane-robert.info/docs/admin-serveurs/linux/find/).
37 |
38 | ## 🧪 Exercices
39 |
40 | ### Exercice 1 : Recherche par nom
41 |
42 | **Objectif** : Rechercher des fichiers par nom, avec et sans casse.
43 |
44 | **Fichier fourni** : `fichiers/rapport1.txt`, `fichiers/rapport2.TXT`
45 |
46 | **Commande à utiliser** :
47 |
48 | ```bash
49 | find . -name "rapport1.txt"
50 | find . -iname "rapport2.txt"
51 | ```
52 |
53 | **Explication** :
54 |
55 | - `-name` : recherche sensible à la casse.
56 | - `-iname` : recherche insensible à la casse.
57 |
58 | ---
59 |
60 | ### Exercice 2 : Filtrage par type de fichier
61 |
62 | **Objectif** : Rechercher des fichiers réguliers ou des liens symboliques.
63 |
64 | **Fichier fourni** : `fichiers/script.sh`, `fichiers/lien_sym`
65 |
66 | **Commande à utiliser** :
67 |
68 | ```bash
69 | find . -type f
70 | find . -type d
71 | ```
72 |
73 | **Explication** :
74 |
75 | - `-type f` : fichiers classiques
76 | - `-type d` : répertoires
77 |
78 | ---
79 |
80 | ### Exercice 3 : Recherche par taille
81 |
82 | **Objectif** : Trouver des fichiers trop gros ou vides.
83 |
84 | **Fichier fourni** : `fichiers/archive.log`, `fichiers/vide.txt`
85 |
86 | **Commande à utiliser** :
87 |
88 | ```bash
89 | find . -type f -size +100k
90 | find . -type f -empty
91 | ```
92 |
93 | **Explication** :
94 |
95 | - `-size +100k` : plus de 100 Ko
96 | - `-empty` : fichiers vides
97 |
98 | ---
99 |
100 | ### Exercice 4 : Recherche par date
101 |
102 | **Objectif** : Identifier des fichiers récents ou anciens.
103 |
104 | **Fichier fourni** : `fichiers/ancien.log`
105 |
106 | **Commande à utiliser** :
107 |
108 | ```bash
109 | find . -type f -mtime +7
110 | find . -type f -mtime -1
111 | ```
112 |
113 | **Explication** :
114 |
115 | - `-mtime +7` : modifiés il y a plus de 7 jours
116 | - `-mtime -1` : modifiés dans les dernières 24 heures
117 |
118 | ---
119 |
120 | ### Exercice 5 : Exécuter des actions sur les fichiers trouvés
121 |
122 | **Objectif** : Modifier les permissions des fichiers `.txt`.
123 |
124 | **Fichier fourni** : `fichiers/secret.txt`
125 |
126 | **Commande à utiliser** :
127 |
128 | ```bash
129 | find . -type f -name "*.txt" -exec chmod 600 {} \;
130 | ```
131 |
132 | **Explication** :
133 |
134 | - `-exec` : exécute une commande sur chaque fichier
135 | - `chmod 600` : permissions lecture/écriture pour l’utilisateur
136 |
137 | ---
138 |
139 | ## 🏁 Challenge à valider
140 |
141 | Pour accéder au challenge final, consultez le fichier `challenge/README.md`.
142 |
143 | ---
144 |
145 | Ce TP vous permettra de comprendre et d’utiliser efficacement la commande `find` pour automatiser vos recherches et traitements de fichiers sur un système Linux.
146 |
--------------------------------------------------------------------------------
/tp-07-02-paquets-dnf/README.md:
--------------------------------------------------------------------------------
1 | # 🖥️ TP : Maîtrisez le gestionnaire de paquets DNF
2 |
3 | ## Introduction
4 |
5 | Ce TP vous apprendra à utiliser **DNF**, le gestionnaire de paquets moderne pour
6 | les distributions Linux basées sur RPM telles que Fedora, RHEL, AlmaLinux ou
7 | Rocky Linux.
8 |
9 | L'objectif est d'être capable de :
10 |
11 | * Installer, mettre à jour et supprimer des paquets
12 | * Rechercher des logiciels
13 | * Gérer les dépôts et groupes de paquets
14 | * Automatiser la maintenance du système
15 |
16 | ## Pré-requis
17 |
18 | Il faut installer **Incus** sur votre mahcine pour ce TP. La procédure
19 | d'installation est décrite dans le fichier [README.md du
20 | projet](https://github.com/stephrobert/linux-training/blob/main/README.md).
21 |
22 | Une fois Incus installé, vous pouvez créer une machine virtuelle Ubuntu 24.04
23 | avec les commandes suivantes depuis le dossier racine du projet `linux-training`
24 | :
25 |
26 | ```bash
27 | incus launch images:rockylinux/9/cloud rocky --config=cloud-init.user-data="$(cat cloud-config.yaml)"
28 | incus alias add login 'exec @ARGS@ -- su -l admin'
29 | incus config device add tp mysharedfolder disk source=$PWD path=/home/ubuntu/linux-training shift=true
30 | ```
31 |
32 | La première commande crée une instance Ubuntu 24.04 sur laquelle sont installés
33 | les packages nécessaires au lancement des tests. La seconde commande permet de
34 | créer un alias pour se connecter facilement à l'instance. La troisième permet de
35 | partager le dossier `linux-training` de votre machine hôte avec l'instance.
36 |
37 | Pour vous connecter à la machine virtuelle, utilisez :
38 |
39 | ```bash
40 | incus login rocky
41 | ```
42 |
43 | On va installer les paquets python nécessaires pour le bon
44 | fonctionnement des tests :
45 |
46 | ```bash
47 | cd /home/ubuntu/linux-training/
48 | ./install.sh
49 | ```
50 |
51 | ## Résumé de la documentation technique
52 |
53 | * `dnf install ` : installe un paquet
54 | * `dnf remove ` : supprime un paquet
55 | * `dnf update` : met à jour tous les paquets
56 | * `dnf search ` : recherche un paquet
57 | * `dnf provides ` : trouve le paquet fournissant un fichier
58 | * `dnf group list/install/remove/info` : gère les groupes de paquets
59 | * `dnf config-manager` : active/désactive un dépôt
60 | * `dnf clean all/metadata/packages` : nettoyage du cache
61 | * `dnf history`, `dnf downgrade`, `dnf reinstall` : commandes avancées
62 | * `dnf-automatic` : outil d'automatisation des mises à jour
63 |
64 | 👉 Documentation complète :
65 | [https://blog.stephane-robert.info/docs/admin-serveurs/linux/dnf/](https://blog.stephane-robert.info/docs/admin-serveurs/linux/dnf/)
66 |
67 | ---
68 |
69 | ## Exercices
70 |
71 | ### Exercice 1 : Installation d'un paquet
72 |
73 | **Objectif :** Installer un serveur HTTP pour la suite du TP.
74 |
75 | ```bash
76 | dnf install httpd
77 | ```
78 |
79 | **Explication :** `dnf install` télécharge et installe le paquet spécifié ainsi
80 | que ses dépendances.
81 |
82 | ### Exercice 2 : Recherche et info
83 |
84 | **Objectif :** Trouver un paquet et obtenir ses détails.
85 |
86 | ```bash
87 | dnf search nano
88 | dnf info nano
89 | ```
90 |
91 | **Explication :** `search` explore les noms/descriptions ; `info` affiche les
92 | détails d'un paquet.
93 |
94 | ### Exercice 3 : Mises à jour sélectives
95 |
96 | **Objectif :** Mettre à jour un paquet spécifique et exclure le noyau.
97 |
98 | ```bash
99 | dnf update nano
100 | dnf --exclude=kernel* update
101 | ```
102 |
103 | **Explication :** `--exclude` empêche certains paquets d'être mis à jour.
104 |
105 | ### Exercice 4 : Groupes de paquets
106 |
107 | **Objectif :** Installer un environnement serveur.
108 |
109 | ```bash
110 | dnf group list
111 | dnf group install "Web Server"
112 | dnf group info "Web Server"
113 | ```
114 |
115 | **Explication :** Les groupes regroupent des paquets selon une fonctionnalité
116 | commune.
117 |
118 | ### Exercice 5 : Nettoyage et résolution
119 |
120 | **Objectif :** Nettoyer et réinstaller un paquet.
121 |
122 | ```bash
123 | dnf clean all
124 | dnf reinstall bash
125 | dnf history
126 | ```
127 |
128 | **Explication :** `clean all` supprime le cache ; `reinstall` remplace les
129 | fichiers du paquet.
130 |
131 | ---
132 |
133 | ## Challenge à valider
134 |
135 | Voir [le dossier challenge](./challenge/README.md) pour les consignes finales et
136 | les tests à réussir avec `pytest` et `testinfra`.
137 |
138 | Bonne pratique !
139 |
--------------------------------------------------------------------------------
/tp-02-03-awk/README.md:
--------------------------------------------------------------------------------
1 | # TP 02-03 : Manipuler des fichiers texte avec `awk`
2 |
3 | ## Introduction
4 |
5 | La commande `awk` est un outil puissant pour le traitement de texte en ligne de
6 | commande. Elle permet de lire des fichiers ligne par ligne, de découper chaque
7 | ligne en champs (colonnes) et d'appliquer des actions conditionnelles sur ces
8 | champs. C'est un langage de programmation à part entière, conçu pour
9 | l'extraction et la transformation de données textuelles. Lisez la documentation
10 | : [Manipuler des fichiers texte avec
11 | awk](https://blog.stephane-robert.info/docs/admin-serveurs/linux/awk/).
12 |
13 | ---
14 |
15 | ## 📚 Résumé de la documentation technique
16 |
17 | - **Nom** : `awk`
18 | - **Type** : Langage de traitement de texte
19 | - **Fonctionnalités principales** :
20 | - Extraction de champs spécifiques
21 | - Filtrage de lignes selon des motifs
22 | - Réalisation de calculs (sommes, moyennes, comptages)
23 | - Reformatage ou restructuration de fichiers texte
24 | - **Syntaxe de base** :
25 |
26 | ```bash
27 | awk 'motif { action }' fichier
28 | ```
29 |
30 | - **motif** : Condition pour exécuter l'action (optionnelle)
31 | - **action** : Opération à réaliser sur la ligne
32 | - **Variables intégrées** :
33 | - `$0` : Ligne entière
34 | - `$1`, `$2`, ... : Champs de la ligne
35 | - `NF` : Nombre de champs dans la ligne
36 | - `NR` : Numéro de la ligne en cours
37 | - `FS` : Séparateur de champs (par défaut, espace ou tabulation)
38 |
39 | ---
40 |
41 | ## 🧪 Exercices
42 |
43 | ### Exercice 1 : Extraire des champs spécifiques
44 |
45 | **Objectif** : Extraire les noms d'utilisateurs et leurs identifiants depuis un
46 | fichier CSV.
47 |
48 | **Fichier fourni** : `fichiers/utilisateurs.csv`
49 |
50 | **Commande à utiliser** :
51 |
52 | ```bash
53 | awk -F';' '{ print $1, $3 }' fichiers/utilisateurs.csv
54 | ```
55 |
56 | **Explication** :
57 |
58 | - `-F';'` : Spécifie que le séparateur de champs est le point-virgule.
59 | - `$1` : Premier champ (nom d'utilisateur).
60 | - `$3` : Troisième champ (identifiant).
61 |
62 | ---
63 |
64 | ### Exercice 2 : Filtrer des lignes selon un motif
65 |
66 | **Objectif** : Afficher les lignes contenant le mot "ERROR" dans un fichier de
67 | logs.
68 |
69 | **Fichier fourni** : `fichiers/logs.txt`
70 |
71 | **Commande à utiliser** :
72 |
73 | ```bash
74 | awk '/ERROR/' fichiers/logs.txt
75 | ```
76 |
77 | **Explication** :
78 |
79 | - `/ERROR/` : Motif recherché dans chaque ligne.
80 | - Si le motif est trouvé, la ligne est affichée.
81 |
82 | ---
83 |
84 | ### Exercice 3 : Compter le nombre de champs par ligne
85 |
86 | **Objectif** : Afficher le nombre de champs pour chaque ligne d'un fichier.
87 |
88 | **Fichier fourni** : `fichiers/passwd.txt`
89 |
90 | **Commande à utiliser** :
91 |
92 | ```bash
93 | awk -F':' '{ print "Ligne " NR ": " NF " champs" }' fichiers/passwd.txt
94 | ```
95 |
96 | **Explication** :
97 |
98 | - `-F':'` : Spécifie que le séparateur de champs est le deux-points.
99 | - `NR` : Numéro de la ligne en cours.
100 | - `NF` : Nombre de champs dans la ligne.
101 |
102 | ---
103 |
104 | ### Exercice 4 : Calculer la somme d'une colonne
105 |
106 | **Objectif** : Calculer le total des ventes à partir d'un fichier CSV.
107 |
108 | **Fichier fourni** : `fichiers/ventes.csv`
109 |
110 | **Commande à utiliser** :
111 |
112 | ```bash
113 | awk -F',' '{ total += $2 } END { print "Total des ventes:", total }' fichiers/ventes.csv
114 | ```
115 |
116 | **Explication** :
117 |
118 | - `-F','` : Spécifie que le séparateur de champs est la virgule.
119 | - `total += $2` : Ajoute la valeur du deuxième champ à la variable `total`.
120 | - `END { print ... }` : Après avoir lu toutes les lignes, affiche le total.
121 |
122 | ---
123 |
124 | ### Exercice 5 : Reformater des lignes
125 |
126 | **Objectif** : Afficher le propriétaire et le nom de chaque fichier dans un
127 | format spécifique.
128 |
129 | **Fichier fourni** : `fichiers/fichiers.txt`
130 |
131 | **Commande à utiliser** :
132 |
133 | ```bash
134 | awk '{ print "Propriétaire: " $3 ", Fichier: " $9 }' fichiers/fichiers.txt
135 | ```
136 |
137 | **Explication** :
138 |
139 | - `$3` : Troisième champ (propriétaire du fichier).
140 | - `$9` : Neuvième champ (nom du fichier).
141 | - Affiche une chaîne formatée avec les informations souhaitées.
142 |
143 | ---
144 |
145 | ## 🏁 Challenge à valider
146 |
147 | Pour accéder au challenge final, consultez le fichier `challenge/README.md`.
148 |
149 | ---
150 |
151 | Ce TP vous permettra de maîtriser les bases de la commande `awk` et de
152 | l'appliquer à des cas concrets de traitement de fichiers texte.
--------------------------------------------------------------------------------
/tp-05-gestion-processus/README.md:
--------------------------------------------------------------------------------
1 | # 🖥️ TP : Gestion des Processus sous Linux
2 |
3 | ## Introduction
4 |
5 | Ce TP a pour objectif d'apprendre à gérer les **processus sous Linux**, qui
6 | représentent les programmes en cours d'exécution. Vous apprendrez à surveiller,
7 | contrôler, ajuster la priorité des processus, et à les arrêter proprement ou de
8 | manière forcée.
9 |
10 | Ces compétences sont essentielles pour :
11 |
12 | * Identifier des processus gourmands en ressources.
13 | * Modifier la priorité d'un processus pour optimiser les performances.
14 | * Arrêter un processus qui pose problème.
15 |
16 | 🔗 Lien vers la documentation : [Gestion des processus
17 | Linux](https://blog.stephane-robert.info/docs/admin-serveurs/linux/gestion-processus/)
18 |
19 | ## Résumé de la documentation technique
20 |
21 | * **ps** : Lister les processus.
22 | * Exemple : `ps aux`
23 | * **top** : Surveiller en temps réel les processus.
24 | * Exemple : `top`
25 | * **htop** : Version améliorée de `top` (si disponible).
26 | * **nice** : Lancer un processus avec une priorité définie.
27 | * Exemple : `nice -n 10 commande`
28 | * **renice** : Modifier la priorité d’un processus en cours.
29 | * Exemple : `renice -n 5 -p 1234`
30 | * **kill** : Envoyer un signal à un processus (ex : arrêt).
31 | * Exemple : `kill -9 1234`
32 | * **killall** : Arrêter tous les processus d’un même nom.
33 | * **pstree** : Visualiser l'arborescence des processus.
34 |
35 | ## Exercices
36 |
37 | ### Exercice 1 : Lister tous les processus
38 |
39 | * **Objectif** : Lister tous les processus actifs sur votre système.
40 | * **Commande** :
41 |
42 | ```bash
43 | ps aux
44 | ```
45 |
46 | **Explication** : Cette commande affiche tous les processus en cours avec des
47 | détails : PID, utilisateur, % CPU, % MEM, etc.
48 |
49 | ---
50 |
51 | ### Exercice 2 : Surveiller les processus en temps réel
52 |
53 | * **Objectif** : Surveiller la consommation des processus en direct.
54 | * **Commande** :
55 |
56 | ```bash
57 | top
58 | ```
59 |
60 | **Explication** : Permet de suivre en temps réel l’état des processus et de
61 | trier par utilisation CPU ou mémoire.
62 |
63 | ---
64 |
65 | ### Exercice 3 : Modifier la priorité d'un processus
66 |
67 | * **Objectif** : Lancer un script en arrière-plan et modifier sa priorité.
68 | * **Commandes** :
69 |
70 | ```bash
71 | ./fichiers/processus.sh &
72 | pgrep -f processus.sh
73 | ```
74 |
75 | Récupérer le PID du processus avec `pgrep` et ajuster la priorité :
76 |
77 | ```bash
78 | renice -n 10 -p [PID]
79 | ```
80 |
81 | **Explication** : Vous lancez le processus avec `&` puis ajustez sa priorité
82 | avec `renice`. Remplacez `[PID]` par l'identifiant du processus.
83 |
84 | On vérifie la priorité avec :
85 |
86 | ```bash
87 | ps -o pid,ni,comm
88 | ```
89 |
90 | **Explication** : `ps -o pid,ni,comm` affiche le PID, la priorité et le nom du
91 | processus. `ni` représente la valeur de nice, qui indique la priorité du
92 | processus. Plus la valeur est élevée, moins le processus est prioritaire.
93 | Vous pouvez également utiliser `htop` pour visualiser les processus et leur
94 | priorité de manière graphique.
95 |
96 | ---
97 |
98 | ### Exercice 4 : Tuer un processus
99 |
100 | * **Objectif** : Tuer le processus créé précédement.
101 | * **Commandes** :
102 |
103 | ```bash
104 | kill -9 [PID]
105 | ```
106 |
107 | **Explication** : `kill -9` envoie le signal SIGKILL pour forcer la terminaison
108 | immédiate du processus.
109 |
110 | ---
111 |
112 | ### Exercice 5 : Suspendre et reprendre un processus
113 |
114 | * **Objectif** : Tester la suspension et la reprise d’un processus.
115 | * **Commandes** :
116 |
117 | ```bash
118 | ./fichiers/processus.sh
119 | ```
120 |
121 | On vient de lancer le script `processus.sh` en avant-plan. Pour le
122 | suspendre, utilisez `Ctrl + Z`. Cela met le processus en pause.
123 |
124 | Pour visualiser les processus suspendus, utilisez :
125 |
126 | ```bash
127 | jobs
128 | ```
129 |
130 | **Explication** : `jobs` affiche la liste des jobs en arrière-plan. Le
131 | processus suspendu sera marqué comme "Stopped".
132 |
133 | Pour le reprendre, utilisez la commande `bg` :
134 |
135 | ```bash
136 | bg %1
137 | ```
138 |
139 | **Explication** : `bg %1` reprend le processus en arrière-plan. Vous pouvez
140 | également le ramener au premier plan avec `fg %1`.
141 |
142 | Tuons les processus en arrière-plan avec :
143 |
144 | ```bash
145 | pgrep -f processus.sh
146 |
147 | kill -9 %[PID]
148 | ```
149 |
150 | ---
151 |
152 | ## 🚩 Challenge à valider
153 |
154 | Rendez-vous dans le dossier [`challenge/`](./challenge/README.md) pour découvrir
155 | et réaliser le challenge final 🎯 !
156 |
157 |
--------------------------------------------------------------------------------
/tp-03-premiers-scripts-shell/README.md:
--------------------------------------------------------------------------------
1 | # TP 03 : Scripting Shell sous Linux
2 |
3 | ## Introduction
4 |
5 | Ce TP a pour objectif de vous initier à l'écriture de scripts Shell sous Linux.
6 | Vous apprendrez à automatiser des tâches simples, à manipuler des variables, à
7 | utiliser des structures de contrôle, à gérer les entrées/sorties, et à
8 | structurer vos scripts avec des fonctions. Ces compétences sont essentielles
9 | pour les administrateurs système et les développeurs DevOps.
10 |
11 | ## Résumé de la documentation
12 |
13 | - **Shell Bash** : Interpréteur de commandes pour exécuter des scripts.
14 | - **Variables** : Affectation avec `nom="valeur"`, usage via `$nom`.
15 | - **Structures de contrôle** : `if`, `else`, `elif`, `for`, `while`.
16 | - **Fonctions** : Organisation du code en blocs réutilisables.
17 | - **Debug** : `bash -x script.sh`, `set -e`, `set -u`.
18 | - **Bonnes pratiques** : utilisation de `shellcheck`.
19 |
20 | Le lien vers la documentation complète est disponible
21 | [ici](https://blog.stephane-robert.info/docs/admin-serveurs/linux/script-shell/).
22 |
23 | ## Tutoriels
24 |
25 | ### Exercice 1 : Bonjour, monde !
26 |
27 | - **Objectif** : Créer un script `bonjour.sh` qui affiche "Bonjour, monde !".
28 |
29 | **Étapes :**
30 |
31 | 1. Crée un fichier nommé `bonjour.sh` avec la commande suivante :
32 |
33 | ```bash
34 | nano bonjour.sh
35 | ```
36 |
37 | 2. Écris le contenu suivant :
38 |
39 | ```bash
40 | #!/bin/bash
41 | echo "Bonjour, monde !"
42 | ```
43 |
44 | 3. Rends le script exécutable :
45 |
46 | ```bash
47 | chmod +x bonjour.sh
48 | ```
49 |
50 | 4. Exécute le script :
51 |
52 | ```bash
53 | ./bonjour.sh
54 | ```
55 |
56 | - **Commandes utilisées** :
57 | - `echo` : affiche une ligne de texte dans le terminal.
58 | - `chmod +x` : rend un fichier exécutable.
59 |
60 | ### Exercice 2 : Bonjour personnalisé
61 |
62 | - **Objectif** : Lire un nom au clavier et afficher "Bonjour, !".
63 |
64 | **Étapes :**
65 |
66 | 1. Crée un fichier `bonjour_perso.sh` :
67 |
68 | ```bash
69 | nano bonjour_perso.sh
70 | ```
71 |
72 | 2. Contenu du script :
73 |
74 | ```bash
75 | #!/bin/bash
76 | echo "Quel est votre prénom ?"
77 | read prenom
78 | echo "Bonjour, $prenom !"
79 | ```
80 |
81 | 3. Rends-le exécutable :
82 |
83 | ```bash
84 | chmod +x bonjour_perso.sh
85 | ./bonjour_perso.sh
86 | ```
87 |
88 | ### Exercice 3 : Pair ou impair
89 |
90 | - **Objectif** : Demander un nombre à l'utilisateur et indiquer s'il est pair ou impair.
91 |
92 | **Étapes :**
93 |
94 | 1. Crée un script `pair_ou_impair.sh` :
95 |
96 | ```bash
97 | nano pair_ou_impair.sh
98 | ```
99 |
100 | 2. Contenu :
101 |
102 | ```bash
103 | #!/bin/bash
104 | echo "Entrez un nombre :"
105 | read nombre
106 | if [ $((nombre % 2)) -eq 0 ]; then
107 | echo "$nombre est pair."
108 | else
109 | echo "$nombre est impair."
110 | fi
111 | ```
112 |
113 | 3. Rends-le exécutable et teste-le.
114 |
115 | ### Exercice 4 : Compteur de lignes
116 |
117 | - **Objectif** : Créer un script qui lit un fichier texte fourni en argument et affiche son nombre de lignes.
118 |
119 | **Étapes :**
120 |
121 | 1. Crée un script `nb_lignes.sh` :
122 |
123 | ```bash
124 | nano nb_lignes.sh
125 | ```
126 |
127 | 2. Contenu :
128 |
129 | ```bash
130 | #!/bin/bash
131 | if [ -f "$1" ]; then
132 | wc -l "$1"
133 | else
134 | echo "Fichier non trouvé."
135 | fi
136 | ```
137 |
138 | 3. Teste avec un fichier texte.
139 |
140 | ### Exercice 5 : Factorielle
141 |
142 | - **Objectif** : Écrire une fonction qui calcule la factorielle d'un nombre donné.
143 |
144 | **Étapes :**
145 |
146 | 1. Crée un script `factorielle.sh` :
147 |
148 | ```bash
149 | nano factorielle.sh
150 | ```
151 |
152 | 2. Contenu :
153 |
154 | ```bash
155 | #!/bin/bash
156 | factorielle() {
157 | n=$1
158 | resultat=1
159 | while [ $n -gt 1 ]; do
160 | resultat=$((resultat * n))
161 | n=$((n - 1))
162 | done
163 | echo $resultat
164 | }
165 |
166 | echo "Entrez un nombre :"
167 | read nombre
168 | factorielle $nombre
169 | ```
170 |
171 | 3. Rendez-le exécutable et testez avec divers nombres.
172 |
173 | ---
174 |
175 | ## 🏁 Challenge à valider
176 |
177 | Consultez le dossier [`challenge/`](./challenge/) pour réaliser un exercice
178 | final permettant de valider vos compétences à l'aide de tests automatisés. Une
179 | fois le challenge terminé, je vous invite à lire mon guide sur [les bonnes
180 | pratiques de développement de scripts
181 | Shell](https://blog.stephane-robert.info/docs/admin-serveurs/linux/scripts-shell-securises/).
182 |
--------------------------------------------------------------------------------
/tp-06-acl/README.md:
--------------------------------------------------------------------------------
1 | # TP : Gestion des ACL sous Linux
2 |
3 | ## Introduction
4 |
5 | Ce TP a pour objectif d'apprendre à gérer les **listes de contrôle d'accès
6 | (ACL)** sous Linux, qui permettent de définir des permissions d'accès plus
7 | granulaires que les simples modes `rwx` classiques. Vous apprendrez à consulter
8 | et modifier les ACL à l'aide des commandes principales `getfacl` et `setfacl`.
9 |
10 | Les ACL sont très utiles pour :
11 |
12 | * Donner des droits spécifiques à certains utilisateurs ou groupes sans changer
13 | le propriétaire.
14 | * Gérer des cas complexes où les permissions standards sont insuffisantes.
15 |
16 | Le lien vers la documentation : [Les ACL
17 | Linux](https://blog.stephane-robert.info/docs/admin-serveurs/linux/acl/)
18 |
19 | ## Résumé de la documentation technique
20 |
21 | * **getfacl** : Permet d'afficher les ACL d'un fichier ou répertoire.
22 |
23 | * Exemple : `getfacl fichier.txt`
24 | * **setfacl** : Permet de définir ou modifier les ACL.
25 |
26 | * Exemple : `setfacl -m u:alice:r fichier.txt` (donne le droit lecture à
27 | l'utilisateur `alice`)
28 | * **Options utiles** :
29 |
30 | * `-m` : modifier une ACL
31 | * `-x` : supprimer une ACL
32 | * `-b` : supprimer toutes les ACL d'un fichier
33 | * `-R` : appliquer de manière récursive
34 | * **Principe** :
35 |
36 | * Une ACL classique : `user:alice:r--`
37 | * Pour les répertoires : ne pas oublier la propagation des ACL avec `d:` (ACL
38 | par défaut)
39 |
40 | ## Exercices
41 |
42 | ### Exercice 1 : Vérifier les ACL existantes
43 |
44 | * **Fichier** : `fichiers/document1.txt`
45 | * **Objectif** : Affichez les ACL actuelles de ce fichier.
46 | * **Commande** :
47 |
48 | ```bash
49 | getfacl fichiers/document1.txt
50 | ```
51 |
52 | **Explication** : Cette commande montre les permissions standards **et** toute
53 | ACL appliquée au fichier.
54 |
55 | ---
56 |
57 | ### Exercice 2 : Ajouter un utilisateur
58 |
59 | Pour les exercices suivants, vous devez créer un utilisateur `etudiant` et un
60 | groupe `stagiaires` sur votre machine. Vous pouvez le faire avec les commandes
61 | suivantes :
62 |
63 | ```bash
64 | sudo useradd etudiant
65 | sudo groupadd stagiaires
66 | sudo usermod -aG stagiaires etudiant
67 | ```
68 |
69 | Nous verrons dans un autre TP comment gérer les utilisateurs et groupes de
70 | manière plus avancée.
71 |
72 | ### Exercice 3 : Ajouter une permission pour un utilisateur
73 |
74 | * **Fichier** : `fichiers/document2.txt`
75 | * **Objectif** : Donnez le droit de lecture à l’utilisateur `etudiant`.
76 | * **Commande** :
77 |
78 | ```bash
79 | setfacl -m u:etudiant:r fichiers/document2.txt
80 | ```
81 |
82 | **Explication** : `-m` indique la modification d'ACL, `u:etudiant:r` signifie
83 | qu'on donne le droit lecture à `etudiant`.
84 |
85 | ---
86 |
87 | ### Exercice 4 : Ajouter une permission pour un groupe
88 |
89 | * **Fichier** : `fichiers/document3.txt`
90 | * **Objectif** : Donnez les droits de lecture et écriture au groupe
91 | `stagiaires`.
92 | * **Commande** :
93 |
94 | ```bash
95 | setfacl -m g:stagiaires:rw fichiers/document3.txt
96 | ```
97 |
98 | **Explication** : `g:stagiaires:rw` cible le groupe `stagiaires` avec les droits
99 | `rw`.
100 |
101 | Vérifier les permissions avec :
102 |
103 | ```bash
104 | getfacl fichiers/document3.txt
105 | ```
106 |
107 | ---
108 |
109 | ### Exercice 4 : Supprimer une ACL
110 |
111 | * **Fichier** : `fichiers/document4.txt`
112 | * **Objectif** : Supprimez l’ACL spécifique pour l’utilisateur `etudiant`.
113 | * **Commande** :
114 |
115 | ```bash
116 | setfacl -x u:etudiant fichiers/document2.txt
117 | ```
118 |
119 | **Explication** : `-x` permet de retirer une entrée ACL précise.
120 |
121 | ---
122 |
123 | ### Exercice 5 : Appliquer des ACL par défaut à un répertoire
124 |
125 | * **Répertoire** : `fichiers/partage/`
126 | * **Objectif** : Assurez-vous que tous les nouveaux fichiers créés dans ce
127 | dossier donnent lecture/écriture au groupe `stagiaires`.
128 | * **Commande** :
129 |
130 | ```bash
131 | setfacl -d -m g:stagiaires:rw fichiers/partage/
132 | ```
133 |
134 | **Explication** : Le `-d` applique une ACL par défaut, utile pour les futurs
135 | fichiers.
136 |
137 | Créez un fichier dans le répertoire `fichiers/partage/` pour vérifier que
138 | l'ACL par défaut fonctionne :
139 |
140 | ```bash
141 | touch fichiers/partage/nouveau_fichier.txt
142 | getfacl fichiers/partage/nouveau_fichier.txt
143 | ```
144 |
145 | **Explication** : Vérifiez que le groupe `stagiaires` a bien les droits
146 | lecture/écriture sur le nouveau fichier créé.
147 |
148 | ---
149 |
150 | ## 🚩 Challenge à valider
151 |
152 | Rendez-vous dans le dossier [`challenge/`](./challenge/README.md) pour découvrir
153 | et réaliser le challenge final !
154 |
155 |
--------------------------------------------------------------------------------
/tp-01-navigation-fichiers/README.md:
--------------------------------------------------------------------------------
1 | # TP 01 : Commandes de base sous Linux
2 |
3 | ## Introduction
4 |
5 | Ce TP vous permettra de maîtriser les commandes Linux de base telles que `ls`, `cd`, `pwd`, `cp`, `mv`, `rm`, `mkdir`, `rmdir`, `chmod`, `chown`, `cat`, `less`, `head`, `tail`, `find`, `locate`. Ces commandes sont essentielles pour naviguer et manipuler les fichiers et répertoires sous Linux.
6 |
7 | Toutes ces commandes sont expliquées dans mon guide sur [les commandes de
8 | base](https://blog.stephane-robert.info/docs/admin-serveurs/linux/commandes/).
9 |
10 | ---
11 |
12 | ## 🔄 Rappels de commandes
13 |
14 | - `ls` : liste les fichiers et répertoires du répertoire courant.
15 | - `cd` : change de répertoire.
16 | - `pwd` : affiche le chemin absolu du répertoire courant.
17 | - `cp` : copie des fichiers ou répertoires.
18 | - `mv` : déplace ou renomme des fichiers ou répertoires.
19 | - `rm` : supprime des fichiers ou répertoires.
20 | - `mkdir` : crée un nouveau répertoire.
21 | - `rmdir` : supprime un répertoire vide.
22 | - `chmod` : modifie les permissions d'un fichier ou répertoire.
23 | - `chown` : change le propriétaire d'un fichier ou répertoire.
24 | - `cat` : affiche le contenu d'un fichier.
25 | - `less` : affiche le contenu d'un fichier page par page.
26 | - `head` : affiche les premières lignes d'un fichier.
27 | - `tail` : affiche les dernières lignes d'un fichier.
28 | - `find` : recherche des fichiers dans une hiérarchie de répertoires.
29 | - `locate` : recherche rapide de fichiers en utilisant une base de données.
30 |
31 | ## 📚 Utiliser l'aide intégrée
32 |
33 | Avant de commencer, installez **tldr**, un outil qui fournit des exemples clairs pour les commandes.
34 |
35 | Installez-le sur Debian/Ubuntu :
36 |
37 | ```bash
38 | sudo apt update
39 | sudo apt install tldr
40 | ```
41 |
42 | Mettez à jour les pages locales :
43 |
44 | ```bash
45 | tldr --update
46 | ```
47 |
48 | Utilisation :
49 |
50 | ```bash
51 | tldr cp
52 | tldr mv
53 | ```
54 |
55 | Vous pouvez aussi utiliser :
56 |
57 | - **Manuel complet** :
58 |
59 | ```bash
60 | man
61 | ```
62 |
63 | - **Aide rapide** :
64 |
65 | ```bash
66 | --help
67 | ```
68 |
69 | Exemple :
70 |
71 | ```bash
72 | man grep
73 | grep --help
74 | ```
75 |
76 | ## 🔢 Tutoriels
77 |
78 | ### Exercice 1 : Navigation basique
79 |
80 | Fichier utilisé : `fichiers/fichier_exercice1.txt`
81 |
82 | 1. Affichez le chemin absolu du répertoire courant :
83 |
84 | ```bash
85 | pwd
86 | ```
87 |
88 | Cette commande vous indique où vous vous situez dans l’arborescence des fichiers.
89 |
90 | 2. Listez le contenu de ce répertoire :
91 |
92 | ```bash
93 | ls
94 | ```
95 |
96 | Cela vous montre les fichiers et dossiers présents.
97 |
98 | ---
99 |
100 | ### Exercice 2 : Création et suppression
101 |
102 | Fichier utilisé : `fichiers/fichier_exercice2.txt`
103 |
104 | 1. Déplacez-vous dans le répertoire `/tmp` :
105 |
106 | ```bash
107 | cd /tmp
108 | ```
109 |
110 | 2. Créez un dossier `test` :
111 |
112 | ```bash
113 | mkdir test
114 | ```
115 |
116 | 3. Supprimez ce dossier :
117 |
118 | ```bash
119 | rmdir test
120 | ```
121 |
122 | 4. Revenez dans le répertoire précédent :
123 |
124 | ```bash
125 | cd -
126 | ```
127 |
128 | ---
129 |
130 | ### Exercice 3 : Manipulation de fichiers
131 |
132 | Fichier utilisé : `fichiers/fichier_exercice3.txt`
133 |
134 | 1. Copiez `fichier_exercice3.txt` vers un nouveau fichier `copie.txt` :
135 |
136 | ```bash
137 | cp fichiers/fichier_exercice3.txt copie.txt
138 | ```
139 |
140 | 2. Renommez-le en `renomme.txt` :
141 |
142 | ```bash
143 | mv copie.txt renomme.txt
144 | ```
145 |
146 | 3. Supprimez `renomme.txt` :
147 |
148 | ```bash
149 | rm renomme.txt
150 | ```
151 |
152 | ---
153 |
154 | ### Exercice 4 : Affichage et recherche dans les fichiers
155 |
156 | Fichier utilisé : `fichiers/fichier_exercice4.txt`
157 |
158 | 1. Affichez les 5 premières lignes du fichier :
159 |
160 | ```bash
161 | head -n 5 fichiers/fichier_exercice4.txt
162 | ```
163 |
164 | 2. Affichez les 3 dernières lignes du fichier :
165 |
166 | ```bash
167 | tail -n 3 fichiers/fichier_exercice4.txt
168 | ```
169 |
170 | 3. Affichez l’intégralité du fichier avec pagination :
171 |
172 | ```bash
173 | less fichiers/fichier_exercice4.txt
174 | ```
175 |
176 | ---
177 |
178 | ### Exercice 5 : Permissions et propriétaires
179 |
180 | Fichier utilisé : `fichiers/fichier_exercice5.txt`
181 |
182 | 1. Donnez les droits d’exécution au fichier :
183 |
184 | ```bash
185 | chmod +x fichiers/fichier_exercice5.txt
186 | ```
187 |
188 | 2. Changez le propriétaire du fichier (nécessite sudo) :
189 |
190 | ```bash
191 | sudo chown $USER fichiers/fichier_exercice5.txt
192 | ```
193 |
194 | ---
195 |
196 | ### Exercice 6 : Recherche de fichiers
197 |
198 | 1. Recherchez tous les fichiers `.txt` dans le répertoire courant et ses sous-répertoires :
199 |
200 | ```bash
201 | find . -name "*.txt"
202 | ```
203 |
204 | 2. Recherchez les fichiers modifiés au cours des 7 derniers jours dans `/var/log` :
205 |
206 | ```bash
207 | find /var/log -mtime -7
208 | ```
209 |
210 | 3. Utilisez `locate` pour trouver un fichier nommé `passwd` :
211 |
212 | ```bash
213 | locate passwd
214 | ```
215 |
216 | ## 🎯 Challenge
217 |
218 | Consultez le dossier [`challenge/`](./challenge/) pour réaliser un exercice final permettant de valider vos compétences à l'aide de tests automatisés.
219 |
220 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
2 | # Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,python
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,linux,python
4 |
5 | ### Linux ###
6 | *~
7 |
8 | # temporary files which can be created if a process still has a handle open of a deleted file
9 | .fuse_hidden*
10 |
11 | # KDE directory preferences
12 | .directory
13 |
14 | # Linux trash folder which might appear on any partition or disk
15 | .Trash-*
16 |
17 | # .nfs files are created when an open file is removed but is still being accessed
18 | .nfs*
19 |
20 | ### Python ###
21 | # Byte-compiled / optimized / DLL files
22 | __pycache__/
23 | *.py[cod]
24 | *$py.class
25 |
26 | # C extensions
27 | *.so
28 |
29 | # Distribution / packaging
30 | .Python
31 | build/
32 | develop-eggs/
33 | dist/
34 | downloads/
35 | eggs/
36 | .eggs/
37 | lib/
38 | lib64/
39 | parts/
40 | sdist/
41 | var/
42 | wheels/
43 | share/python-wheels/
44 | *.egg-info/
45 | .installed.cfg
46 | *.egg
47 | MANIFEST
48 |
49 | # PyInstaller
50 | # Usually these files are written by a python script from a template
51 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
52 | *.manifest
53 | *.spec
54 |
55 | # Installer logs
56 | pip-log.txt
57 | pip-delete-this-directory.txt
58 |
59 | # Unit test / coverage reports
60 | htmlcov/
61 | .tox/
62 | .nox/
63 | .coverage
64 | .coverage.*
65 | .cache
66 | nosetests.xml
67 | coverage.xml
68 | *.cover
69 | *.py,cover
70 | .hypothesis/
71 | .pytest_cache/
72 | cover/
73 |
74 | # Translations
75 | *.mo
76 | *.pot
77 |
78 | # Django stuff:
79 | local_settings.py
80 | db.sqlite3
81 | db.sqlite3-journal
82 |
83 | # Flask stuff:
84 | instance/
85 | .webassets-cache
86 |
87 | # Scrapy stuff:
88 | .scrapy
89 |
90 | # Sphinx documentation
91 | docs/_build/
92 |
93 | # PyBuilder
94 | .pybuilder/
95 | target/
96 |
97 | # Jupyter Notebook
98 | .ipynb_checkpoints
99 |
100 | # IPython
101 | profile_default/
102 | ipython_config.py
103 |
104 | # pyenv
105 | # For a library or package, you might want to ignore these files since the code is
106 | # intended to run in multiple environments; otherwise, check them in:
107 | # .python-version
108 |
109 | # pipenv
110 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
111 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
112 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
113 | # install all needed dependencies.
114 | #Pipfile.lock
115 |
116 | # poetry
117 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
118 | # This is especially recommended for binary packages to ensure reproducibility, and is more
119 | # commonly ignored for libraries.
120 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
121 | #poetry.lock
122 |
123 | # pdm
124 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
125 | #pdm.lock
126 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
127 | # in version control.
128 | # https://pdm.fming.dev/#use-with-ide
129 | .pdm.toml
130 |
131 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
132 | __pypackages__/
133 |
134 | # Celery stuff
135 | celerybeat-schedule
136 | celerybeat.pid
137 |
138 | # SageMath parsed files
139 | *.sage.py
140 |
141 | # Environments
142 | .env
143 | .venv
144 | env/
145 | venv/
146 | ENV/
147 | env.bak/
148 | venv.bak/
149 |
150 | # Spyder project settings
151 | .spyderproject
152 | .spyproject
153 |
154 | # Rope project settings
155 | .ropeproject
156 |
157 | # mkdocs documentation
158 | /site
159 |
160 | # mypy
161 | .mypy_cache/
162 | .dmypy.json
163 | dmypy.json
164 |
165 | # Pyre type checker
166 | .pyre/
167 |
168 | # pytype static type analyzer
169 | .pytype/
170 |
171 | # Cython debug symbols
172 | cython_debug/
173 |
174 | # PyCharm
175 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
176 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
177 | # and can be added to the global gitignore or merged into this file. For a more nuclear
178 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
179 | #.idea/
180 |
181 | ### Python Patch ###
182 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
183 | poetry.toml
184 |
185 | # ruff
186 | .ruff_cache/
187 |
188 | # LSP config files
189 | pyrightconfig.json
190 |
191 | ### VisualStudioCode ###
192 | .vscode/*
193 | !.vscode/settings.json
194 | !.vscode/tasks.json
195 | !.vscode/launch.json
196 | !.vscode/extensions.json
197 | !.vscode/*.code-snippets
198 |
199 | # Local History for Visual Studio Code
200 | .history/
201 |
202 | # Built Visual Studio Code Extensions
203 | *.vsix
204 |
205 | ### VisualStudioCode Patch ###
206 | # Ignore all local history of files
207 | .history
208 | .ionide
209 |
210 | # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,python
211 |
212 | # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
213 |
214 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TP Linux pour Administrateurs Systèmes
2 |
3 | Bienvenue dans ce projet de **Travaux Pratiques Linux** !
4 |
5 | Ces TP vous guideront dans l'apprentissage pratique de l'**administration
6 | système Linux**. Chaque TP est organisé dans un **sous-dossier** avec son propre
7 | énoncé. Au début, les explications seront détaillées, mais très vite, vous serez
8 | plus autonome dans l'exécution des tâches demandées.
9 |
10 | ## Pré-requis
11 |
12 | ### Environnement
13 |
14 | - Une machine (ou wsl2 pour ceux qui sont sous windows) avec une distribution
15 | **Debian** ou une de ses dérivées fraîchement installée (par exemple Debian
16 | 12).
17 | - **Accès administrateur (root)** ou un utilisateur pouvant utiliser `sudo`.
18 | - **Virtualisation activée** dans le BIOS/UEFI (Intel VT-x ou AMD-V), car
19 | certains TP utiliseront la **virtualisation** pour manipuler d'autres
20 | distributions Linux.
21 |
22 | **Conseil :** vérifiez si la virtualisation est activée :
23 |
24 | ```bash
25 | egrep -c '(vmx|svm)' /proc/cpuinfo
26 | ```
27 |
28 | Un résultat supérieur à 0 indique que la virtualisation est active.
29 |
30 | ### Logiciels
31 |
32 | - Installer **Python 3** et **pip** :
33 |
34 | ```bash
35 | sudo apt update
36 | sudo apt install python3 python3-pip
37 | ```
38 |
39 | - Installer **pytest** et **testinfra** pour valider vos exercices :
40 |
41 | ```bash
42 | pip install pipx --user
43 | pipx install pytest
44 | pipx inject pytest pytest-testinfra
45 | ```
46 |
47 | - Cloner ce dépôt :
48 |
49 | ```bash
50 | git clone
51 | cd
52 | ```
53 |
54 | **Vérifications rapides :**
55 |
56 | ```bash
57 | python3 --version
58 | pytest --version
59 | ```
60 |
61 | A partir du TP 7, il sera nécessaire d'installer **Incus** (anciennement LXD).
62 | En effet, Incus est un gestionnaire de conteneurs et de machines virtuelles qui
63 | vous permet de créer et gérer des environnements virtuels. Il est
64 | particulièrement utile pour les TP qui risquent d'endommager votre instance de Linux.
65 |
66 | Pour l'installer, exécutez les commandes suivantes :
67 |
68 | ```bash
69 | sudo apt install incus
70 | ```
71 |
72 | Initialiser Incus :
73 |
74 | ```bash
75 | sudo incus init --minimal
76 | ```
77 |
78 | ## Documentation obligatoire
79 |
80 | Avant de commencer un TP, vous devez **lire la documentation** liée au sujet sur
81 | [mon site de documentation Linux](https://blog.stephane-robert.info/docs/).
82 |
83 | Chaque énoncé précisera quelle section lire.
84 | **Aucune aide ne sera donnée sur des notions qui y sont expliquées.**
85 |
86 | **Exemples de lectures recommandées :**
87 |
88 | - [Introduction aux Serveurs
89 | Linux](https://blog.stephane-robert.info/docs/admin-serveurs/linux/)
90 | - [Apprendre les commandes Linux de
91 | base](https://blog.stephane-robert.info/docs/admin-serveurs/linux/commandes/)
92 |
93 | ## Structure du projet
94 |
95 | Chaque TP est placé dans un **sous-dossier** indépendant :
96 |
97 | ```bash
98 | /Linux-training/
99 | │
100 | ├── tp01-navigation-fichiers/
101 | │ └── README.md
102 | │ └── challenge/
103 | │ ├── README.md
104 | │ └── tests/
105 | │ └── test_tp.py
106 | ├── tp-02-commandes-avancees/
107 | │ └── README.md
108 | │ └── challenge/
109 | │ ├── README.md
110 | │ └── tests/
111 | │ └── test_tp.py
112 | ├── ...
113 | ```
114 |
115 | Chaque sous-dossier contient :
116 |
117 | - Un fichier `README.md` avec les consignes.
118 | - Un dossier `challenge/` avec :
119 | - Un fichier `README.md` avec les consignes.
120 | - Un dossier tests contenant un fichier `test_tp.py` pour valider automatiquement votre travail.
121 |
122 | ## Comment travailler sur un TP
123 |
124 | 1. Lire la documentation liée au sujet sur [le
125 | site](https://blog.stephane-robert.info/docs/).
126 | 2. Lire attentivement le `README.md` contenu dans le dossier du TP.
127 | 3. Effectuer les tâches demandées dans votre terminal.
128 | 4. Relever le challenge dans le dossier `challenge/` :
129 | 5. Vérifier votre travail avec **pytest** :
130 |
131 | ```bash
132 | pytest -v
133 | ```
134 |
135 | Les tests vous indiqueront si votre solution est correcte.
136 |
137 | ## Important
138 |
139 | - **Aucune réponse n’est donnée** dans les énoncés après les premiers TP.
140 | - **Cherchez par vous-même** avec l'aide des commandes Linux (`--help`, `man`,
141 | etc.).
142 | - **Validez vos résultats** uniquement via les tests automatisés.
143 | - **Si vous bloquez**, n'hésitez pas à demander de l'aide sur
144 | [le discord](https://blog.stephane-robert.info/docs/discord/).
145 |
146 | ## Mise à jour du dépôt
147 |
148 | Je vais continuer à mettre à jour ce dépôt avec de nouveaux exercices et des
149 | améliorations. Pour récupérer les dernières modifications, vous pouvez
150 | simplement exécuter :
151 |
152 | ```bash
153 | git pull origin main
154 | ```
155 |
156 | ## Contribuer
157 |
158 | Bien entendu, vous êtes invités à contribuer à ce dépôt en proposant des
159 | améliorations ou en corrigeant des erreurs. N'hésitez pas à ouvrir une **issue**
160 | ou à soumettre une **pull request**.
161 |
162 | Plus d'infos [ici](https://github.com/stephrobert/containers-training/blob/main/contributing.md)
163 |
164 | ## Me soutenir
165 |
166 | Si vous appréciez ce travail et souhaitez me soutenir, vous pouvez me payer un
167 | café ☕️:
168 |
169 | [](https://ko-fi.com/stephanerobert89902)
170 |
171 | ## Copyright et licence
172 |
173 | Tous les contenus contenus dans ce repo sont :
174 |
175 | - Copyright ©2025 Stéphane Robert
176 | - Distribués sous [licence Creative Commons BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
177 |
178 | 
179 |
--------------------------------------------------------------------------------
/tp-02-00-commandes-avancees/README.md:
--------------------------------------------------------------------------------
1 | # TP 02 : Commandes avancées Linux
2 |
3 | ## 🧠 Introduction
4 |
5 | Ce TP vous permettra de maîtriser des commandes Linux avancées essentielles pour
6 | l'administration système. Vous apprendrez à manipuler des fichiers, gérer des
7 | processus et analyser l'utilisation du disque.
8 |
9 | Ces commandes sont expliquées dans mon guide sur [les commandes
10 | avancées](https://blog.stephane-robert.info/docs/admin-serveurs/linux/commandes-avancees/).
11 |
12 | ## 📚 Résumé des commandes abordées
13 |
14 | - **`uname`** : affiche des informations sur le système.
15 | - **`free`** : affiche l'utilisation de la mémoire.
16 | - **`diff`** : compare le contenu de deux fichiers.
17 | - **`ps`** : affiche les processus en cours.
18 | - **`top`** : affiche les processus en temps réel.
19 | - **`cut`** : extrait des sections de lignes de fichiers.
20 | - **`tr`** : traduit ou supprime des caractères.
21 | - **`paste`** : fusionne des lignes de fichiers.
22 | - **`join`** : joint des lignes de deux fichiers sur une clé commune.
23 | - **`comm`** : compare deux fichiers ligne par ligne.
24 | - **`nl`** : numérote les lignes d'un fichier.
25 | - **`tee`** : lit l'entrée standard et écrit dans un fichier et la sortie
26 | standard.
27 | - **`rev`** : inverse les lignes caractère par caractère.
28 | - **`fold`** : plie les lignes longues.
29 | - **`sed`** : édite des fichiers en ligne de commande.
30 | - **`awk`** : traite et analyse des fichiers texte.
31 |
32 | ## 🧪 Exercices
33 |
34 | ### Exercice 1 : Afficher des informations sur le système
35 |
36 | **Objectif** : Utiliser `uname` pour afficher des informations sur le système.
37 |
38 | **Commande** :
39 |
40 | ```bash
41 | uname -a
42 | ```
43 |
44 | **Explication** : `uname -a` affiche toutes les informations disponibles sur le
45 | système.
46 |
47 | **Tester les autres options de `uname`** : `-a`, `-s`, `-r`, `-v`, `-m`, `-p`,
48 | `-i`, `-o`
49 |
50 | ---
51 |
52 | ### Exercice 2 : Afficher l'utilisation de la mémoire
53 |
54 | **Objectif** : Utiliser `free` pour afficher l'utilisation de la mémoire.
55 |
56 | **Commande** :
57 |
58 | ```bash
59 | free -h
60 | ```
61 |
62 |
63 | **Explication** : `free -h` affiche l'utilisation de la mémoire en format
64 | lisible.
65 |
66 | **Tester les autres options de `free`** `-h`, `-m`, `-g`
67 |
68 | ---
69 |
70 | ### Exercice 3 : Comparer deux fichiers
71 |
72 | **Fichiers** : `fichiers/exercice3a.txt`, `fichiers/exercice3b.txt`
73 |
74 | **Objectif** : Utiliser `diff` pour comparer deux fichiers.
75 |
76 | **Commande** :
77 |
78 | ```bash
79 | diff fichiers/exercice3a.txt fichiers/exercice3b.txt
80 | 2c2
81 | < ligne2
82 | ---
83 | > ligneModifiee
84 | ```
85 |
86 | **Explication** :
87 |
88 | - `2c2` : indique que **la ligne 2** du premier fichier est **changée** (`c`
89 | pour "change") par rapport à la ligne 2 du second fichier.
90 | - `< ligne2` : montre le contenu de la ligne 2 dans le **premier fichier**
91 | (`exercice3a.txt`) — ici : `ligne2`.
92 | - `>` ligneModifiee` : montre le contenu de la ligne 2 dans le **second
93 | fichier** (`exercice3b.txt`) — ici : `ligneModifiee`.
94 |
95 | **Tester les autres options de `diff`** : `-u`, `-c`, `-y`
96 |
97 | ---
98 |
99 | ### Exercice 4 : Afficher les processus en cours
100 |
101 | **Objectif** : Utiliser `ps` pour afficher les processus en cours.
102 |
103 | **Commandes** :
104 |
105 | ```bash
106 | ps aux
107 | ```
108 |
109 | **Explication** : `ps aux` affiche tous les processus en cours.
110 |
111 | **Tester les autres options de `ps`** : `a`, `u`, `x`;
112 |
113 | La commande ps affiche les processus en cours d'exécution sur le système. Les
114 | options `a`, `u` et `x` permettent d'afficher des informations détaillées sur
115 | les processus, y compris ceux qui n'ont pas de terminal associé.
116 |
117 | ### Exercice 5 : Manipuler des fichiers texte
118 |
119 | #### 🧪 Exercice 5.1 : Extraire et transformer des colonnes
120 |
121 | **Fichier** : `fichiers/exercice5.txt` (format CSV : `nom,age`)
122 |
123 | **Objectif** : Extraire les prénoms et les convertir en majuscules.
124 |
125 | **Commandes** :
126 |
127 | ```bash
128 | cut -d',' -f1 fichiers/exercice5.txt | tr 'a-z' 'A-Z'
129 | ```
130 |
131 | **Explication** :
132 |
133 | - `cut -d',' -f1` : extrait la première colonne, ici les prénoms.
134 | - `tr 'a-z' 'A-Z'` : transforme les minuscules en majuscules.
135 |
136 | ---
137 |
138 | #### 🧪 Exercice 5.2 : Rechercher et remplacer dans un fichier
139 |
140 | **Fichier** : `fichiers/exercice5.txt`
141 |
142 | **Objectif** : Remplacer tous les âges "30" par "31".
143 |
144 | **Commande** :
145 |
146 | ```bash
147 | sed 's/30/31/g' fichiers/exercice5.txt
148 | ```
149 |
150 | **Explication** :
151 |
152 | - `sed` permet de faire des remplacements avec des expressions régulières.
153 | - Ici, on remplace toutes les occurrences de `30` par `31`.
154 |
155 | ---
156 |
157 | #### 🧪 Exercice 5.3 : Filtrer et numéroter des lignes
158 |
159 | **Fichier** : `fichiers/exercice5.txt`
160 |
161 | **Objectif** : Afficher uniquement les personnes âgées de plus de 30 ans et
162 | numéroter les lignes.
163 |
164 | **Commande** :
165 |
166 | ```bash
167 | awk -F',' '$2 > 30' fichiers/exercice5.txt | nl
168 | ```
169 |
170 | **Explication** :
171 |
172 | - `awk -F',' '$2 > 30'` : filtre les lignes où l'âge (2ᵉ champ) est supérieur à
173 | 30.
174 | - `nl` : numérote les lignes.
175 |
176 | ---
177 |
178 | ## 🏁 Challenge à valider
179 |
180 | Consultez le dossier [`challenge/`](./challenge/) pour réaliser un exercice
181 | final permettant de valider vos compétences à l'aide de tests automatisés.
182 |
183 | ## Aller plus loin
184 |
185 | J'ai commencé à rédiger des TP sur certaines de ces commandes. Vous pouvez
186 | trouver ces TP dans les sous-dossiers suivant :
187 |
188 | - [xargs](https://github.com/stephrobert/linux-training/tree/main/tp-02-1-xargs)
189 | - [awk](https://github.com/stephrobert/linux-training/tree/main/tp-02-3-awk)
190 |
191 | D'autres TP seront ajoutés au fur et à mesure de mes avancées.
--------------------------------------------------------------------------------
/tp-07-01-paquets-apt/README.md:
--------------------------------------------------------------------------------
1 | # Maîtriser APT sous Debian et ses dérivés
2 |
3 | ## 🏁 Introduction
4 |
5 | Dans ce TP, vous allez apprendre à utiliser **APT (Advanced Package Tool)**, le
6 | gestionnaire de paquets incontournable des distributions Debian et dérivées
7 | (Ubuntu, Kali Linux, etc.). Vous manipulerez les commandes essentielles pour
8 | installer, mettre à jour, rechercher et supprimer des paquets, et découvrirez
9 | comment gérer les dépôts logiciels en toute sécurité.
10 |
11 | 🎯 **Objectif** : Être autonome dans la gestion des logiciels avec APT pour
12 | maintenir un système à jour et sécurisé.
13 |
14 | ---
15 |
16 | ## Pré-requis
17 |
18 | Il faut installer **Incus** sur votre machine pour ce TP. La procédure
19 | d'installation est décrite dans le fichier [README.md du
20 | projet](https://github.com/stephrobert/linux-training/blob/main/README.md).
21 |
22 | Une fois Incus installé, vous pouvez créer une machine virtuelle Ubuntu 24.04
23 | avec les commandes suivantes depuis le dossier racine du projet `linux-training`
24 | :
25 |
26 | ```bash
27 | incus launch images:ubuntu/24.04/cloud ubuntu --config=cloud-init.user-data="$(cat cloud-config.yaml)"
28 | incus alias add login 'exec @ARGS@ -- su -l admin'
29 | incus config device add tp mysharedfolder disk source=$PWD path=/home/ubuntu/linux-training shift=true
30 | ```
31 |
32 | La première commande crée une instance Ubuntu 24.04 sur laquelle sont installés
33 | les packages nécessaires au lancement des tests. La seconde commande permet de
34 | créer un alias pour se connecter facilement à l'instance. La troisième permet de
35 | partager le dossier `linux-training` de votre machine hôte avec l'instance.
36 |
37 | Pour vous connecter à la machine virtuelle, utilisez :
38 |
39 | ```bash
40 | incus login tp
41 | ```
42 |
43 | On va installer les paquets python nécessaires pour le bon
44 | fonctionnement des tests :
45 |
46 | ```bash
47 | cd /home/ubuntu/linux-training/
48 | ./install.sh
49 | ```
50 |
51 | ---
52 |
53 | ## 📚 Résumé de la documentation
54 |
55 | * `apt update` : Met à jour la liste des paquets disponibles.
56 | * `apt upgrade` : Met à jour les paquets installés.
57 | * `apt full-upgrade` : Met à jour en gérant les changements complexes de
58 | dépendances.
59 | * `apt install ` : Installe un paquet (et ses dépendances).
60 | * `apt remove ` : Supprime un paquet en gardant la configuration.
61 | * `apt purge ` : Supprime un paquet + sa configuration.
62 | * `apt search ` : Recherche des paquets.
63 | * `apt show ` : Affiche des informations détaillées.
64 | * `apt clean` / `apt autoclean` : Nettoie le cache APT.
65 | * Gestion des dépôts : `/etc/apt/sources.list` et `/etc/apt/sources.list.d/`
66 | * Ajout sécurisé d'un dépôt : clé GPG + dépôt avec option `signed-by`.
67 |
68 | 👉 Documentation complète :
69 | [https://blog.stephane-robert.info/docs/admin-serveurs/linux/apt/](https://blog.stephane-robert.info/docs/admin-serveurs/linux/apt/)
70 |
71 | ---
72 |
73 | ## 🛠️ Exercices
74 |
75 | ### Exercice 1 : Mettre à jour la liste des paquets
76 |
77 | * **Fichier fourni** : aucun
78 | * **Action** :
79 |
80 | 1. Exécutez la commande `sudo apt update`.
81 | 2. Observez les lignes de sortie.
82 |
83 | 👉 **Explication** : Cette commande interroge tous les dépôts pour mettre à jour
84 | le cache local (dans `/var/lib/apt/lists`). Elle ne modifie pas le système
85 | lui-même.
86 |
87 | ### Exercice 2 : Installer et supprimer un paquet
88 |
89 | * **Fichier fourni** : aucun
90 | * **Action** :
91 |
92 | 1. Installez le paquet `htop`.
93 |
94 | ```bash
95 | sudo apt install htop
96 | ```
97 |
98 | 2. Vérifiez son installation avec :
99 |
100 | ```bash
101 | htop --version
102 | ```
103 |
104 | 3. Supprimez-le sans effacer la configuration :
105 |
106 | ```bash
107 | sudo apt remove htop
108 | ```
109 |
110 | 4. Installez-le package `curl` :
111 |
112 | ```bash
113 | sudo apt install curl -y
114 | ```
115 |
116 | 👉 **Explication** : `install` ajoute le paquet et ses dépendances ; `remove`
117 | garde la config pour une réinstallation future.
118 |
119 | ### Exercice 3 : Nettoyer l'espace disque
120 |
121 | * **Action** :
122 |
123 | 1. Listez les fichiers présents dans `/var/cache/apt/archives/`.
124 | 2. Exécutez :
125 |
126 | ```bash
127 | sudo apt clean
128 | ```
129 |
130 | 3. Vérifiez que le cache est vidé.
131 |
132 | 👉 **Explication** : `apt clean` supprime tous les fichiers `.deb` téléchargés,
133 | utile pour libérer de l'espace disque.
134 |
135 | ### Exercice 4 : Explorer un paquet
136 |
137 | * **Action** :
138 |
139 | 1. Utilisez `apt search` pour trouver le package install le serveur ssh.
140 | 2. Affichez ses détails avec :
141 |
142 | ```bash
143 | apt show
144 | ```
145 |
146 | 👉 **Explication** : `search` parcourt la base locale des paquets et `show`
147 | affiche toutes les infos : dépendances, description, etc.
148 |
149 | ### Exercice 5 : Ajouter un dépôt et mettre à jour
150 |
151 | * **Action** :
152 |
153 | 1. Editez le fichier dans `/etc/apt/sources.list.d/docker.list` :
154 |
155 | ```bash
156 | sudo vi /etc/apt/sources.list.d/docker.list
157 | ```
158 |
159 | 2. Ajoutez la ligne suivante :
160 |
161 | ```bash
162 | deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable
163 | ```
164 |
165 | 3. Ajoutez la clé GPG :
166 |
167 | ```bash
168 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
169 | sudo chmod a+r /etc/apt/keyrings/docker.asc
170 | ```
171 |
172 | 4. Mettez à jour la liste des paquets :
173 |
174 | ```bash
175 | sudo apt update
176 | ```
177 |
178 | 5. Installez le paquet `docker-ce` :
179 |
180 | ```bash
181 | sudo apt install docker-ce
182 | ```
183 |
184 | 👉 **Explication** : APT détecte automatiquement les nouveaux dépôts ajoutés
185 | dans `sources.list.d`. La clé GPG assure l'intégrité des paquets et la sécurité
186 | de l'installation. La commande `apt update` met à jour la liste des paquets
187 | disponibles, y compris ceux du dépôt Docker. L'installation de `docker-ce`
188 | permet d'utiliser Docker sur votre système. Vous pouvez vérifier son
189 | installation avec :
190 |
191 | ```bash
192 | docker --version
193 | ```
194 |
195 | ---
196 |
197 | ## 🚀 Challenge à valider
198 |
199 | 📂 Rendez-vous dans le dossier [`challenge/`](./challenge/README.md) pour
200 | découvrir votre mission finale !
201 |
202 | ---
203 |
204 | ✅ Bon courage et amusez-vous avec APT 😄
205 |
--------------------------------------------------------------------------------