├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── cloud-config.yaml ├── contributing.md ├── install.sh ├── requirements.txt ├── tp-01-navigation-fichiers ├── README.md ├── challenge │ ├── README.md │ └── tests │ │ └── test_tp.py ├── fichier_exercice1.txt ├── fichier_exercice2.txt ├── fichier_exercice3.txt ├── fichier_exercice4.txt └── fichier_exercice5.txt ├── tp-02-00-commandes-avancees ├── README.md ├── challenge │ ├── README.md │ ├── tests │ │ └── test_tp.py │ └── utilisateurs.csv └── fichiers │ ├── exercice3a.txt │ ├── exercice3b.txt │ ├── exercice5.txt │ ├── exercice5a.txt │ └── exercice5b.txt ├── tp-02-01-xargs ├── README.md ├── challenge │ ├── README.md │ └── tests │ │ └── test_xargs.py └── fichiers │ ├── exemples1.txt │ ├── exemples2.txt │ ├── fichiers_avec_espaces.txt │ └── liste_fichiers.txt ├── tp-02-02-sed ├── README.md ├── fichiers │ ├── apache.conf │ ├── logs.txt │ ├── report.csv │ ├── serveur.conf │ └── users.txt └── modifs.sed ├── tp-02-03-awk ├── README.md ├── challenge │ ├── README.md │ ├── tests │ │ └── test_tp.py │ └── ventes.csv └── fichiers │ ├── fichiers.txt │ ├── logs.txt │ ├── passwd.txt │ ├── utilisateurs.csv │ └── ventes.csv ├── tp-02-04-find ├── README.md ├── challenge │ ├── README.md │ └── tests │ │ └── test_arborescence.py └── fichiers │ ├── ancien.log │ ├── archive.log │ ├── gros.log │ ├── rapport1.txt │ ├── rapport2.TXT │ ├── script.sh │ ├── secret.txt │ └── vide.txt ├── tp-03-premiers-scripts-shell ├── README.md └── challenge │ ├── README.md │ ├── majeurs.txt │ ├── tests │ └── test_tp.py │ └── utilisateurs.csv ├── tp-05-gestion-processus ├── README.md └── fichiers │ └── processus.sh ├── tp-06-acl ├── README.md ├── challenge │ ├── README.md │ ├── document1.txt │ ├── document2.txt │ └── tests │ │ └── test_tp.py └── fichiers │ ├── document1.txt │ ├── document2.txt │ ├── document3.txt │ ├── document4.txt │ └── partage │ ├── nouveau_fichier.txt │ └── readme.txt └── tp-07-paquets-apt ├── README.md └── challenge ├── README.md └── tests └── test_tp.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: stephanerobert89902 2 | -------------------------------------------------------------------------------- /.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 | *.log 80 | local_settings.py 81 | db.sqlite3 82 | db.sqlite3-journal 83 | 84 | # Flask stuff: 85 | instance/ 86 | .webassets-cache 87 | 88 | # Scrapy stuff: 89 | .scrapy 90 | 91 | # Sphinx documentation 92 | docs/_build/ 93 | 94 | # PyBuilder 95 | .pybuilder/ 96 | target/ 97 | 98 | # Jupyter Notebook 99 | .ipynb_checkpoints 100 | 101 | # IPython 102 | profile_default/ 103 | ipython_config.py 104 | 105 | # pyenv 106 | # For a library or package, you might want to ignore these files since the code is 107 | # intended to run in multiple environments; otherwise, check them in: 108 | # .python-version 109 | 110 | # pipenv 111 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 112 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 113 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 114 | # install all needed dependencies. 115 | #Pipfile.lock 116 | 117 | # poetry 118 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 119 | # This is especially recommended for binary packages to ensure reproducibility, and is more 120 | # commonly ignored for libraries. 121 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 122 | #poetry.lock 123 | 124 | # pdm 125 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 126 | #pdm.lock 127 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 128 | # in version control. 129 | # https://pdm.fming.dev/#use-with-ide 130 | .pdm.toml 131 | 132 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 133 | __pypackages__/ 134 | 135 | # Celery stuff 136 | celerybeat-schedule 137 | celerybeat.pid 138 | 139 | # SageMath parsed files 140 | *.sage.py 141 | 142 | # Environments 143 | .env 144 | .venv 145 | env/ 146 | venv/ 147 | ENV/ 148 | env.bak/ 149 | venv.bak/ 150 | 151 | # Spyder project settings 152 | .spyderproject 153 | .spyproject 154 | 155 | # Rope project settings 156 | .ropeproject 157 | 158 | # mkdocs documentation 159 | /site 160 | 161 | # mypy 162 | .mypy_cache/ 163 | .dmypy.json 164 | dmypy.json 165 | 166 | # Pyre type checker 167 | .pyre/ 168 | 169 | # pytype static type analyzer 170 | .pytype/ 171 | 172 | # Cython debug symbols 173 | cython_debug/ 174 | 175 | # PyCharm 176 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 177 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 178 | # and can be added to the global gitignore or merged into this file. For a more nuclear 179 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 180 | #.idea/ 181 | 182 | ### Python Patch ### 183 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 184 | poetry.toml 185 | 186 | # ruff 187 | .ruff_cache/ 188 | 189 | # LSP config files 190 | pyrightconfig.json 191 | 192 | ### VisualStudioCode ### 193 | .vscode/* 194 | !.vscode/settings.json 195 | !.vscode/tasks.json 196 | !.vscode/launch.json 197 | !.vscode/extensions.json 198 | !.vscode/*.code-snippets 199 | 200 | # Local History for Visual Studio Code 201 | .history/ 202 | 203 | # Built Visual Studio Code Extensions 204 | *.vsix 205 | 206 | ### VisualStudioCode Patch ### 207 | # Ignore all local history of files 208 | .history 209 | .ionide 210 | 211 | # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,python 212 | 213 | # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) 214 | 215 | -------------------------------------------------------------------------------- /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 windowss) 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 | - Initialiser Incus : 72 | 73 | ```bash 74 | sudo inucs init --minimal 75 | ``` 76 | 77 | ## Documentation obligatoire 78 | 79 | Avant de commencer un TP, vous devez **lire la documentation** liée au sujet sur 80 | [mon site de documentation Linux](https://blog.stephane-robert.info/docs/). 81 | 82 | Chaque énoncé précisera quelle section lire. 83 | **Aucune aide ne sera donnée sur des notions qui y sont expliquées.** 84 | 85 | **Exemples de lectures recommandées :** 86 | 87 | - [Introduction aux Serveurs 88 | Linux](https://blog.stephane-robert.info/docs/admin-serveurs/linux/) 89 | - [Apprendre les commandes Linux de 90 | base](https://blog.stephane-robert.info/docs/admin-serveurs/linux/commandes/) 91 | 92 | ## Structure du projet 93 | 94 | Chaque TP est placé dans un **sous-dossier** indépendant : 95 | 96 | ```bash 97 | /Linux-training/ 98 | │ 99 | ├── tp01-navigation-fichiers/ 100 | │ └── README.md 101 | │ └── challenge/ 102 | │ ├── README.md 103 | │ └── tests/ 104 | │ └── test_tp.py 105 | ├── tp-02-commandes-avancees/ 106 | │ └── README.md 107 | │ └── challenge/ 108 | │ ├── README.md 109 | │ └── tests/ 110 | │ └── test_tp.py 111 | ├── ... 112 | ``` 113 | 114 | Chaque sous-dossier contient : 115 | 116 | - Un fichier `README.md` avec les consignes. 117 | - Un dossier `challenge/` avec : 118 | - Un fichier `README.md` avec les consignes. 119 | - Un dossier tests contenant un fichier `test_tp.py` pour valider automatiquement votre travail. 120 | 121 | ## Comment travailler sur un TP 122 | 123 | 1. Lire la documentation liée au sujet sur [le 124 | site](https://blog.stephane-robert.info/docs/). 125 | 2. Lire attentivement le `README.md` contenu dans le dossier du TP. 126 | 3. Effectuer les tâches demandées dans votre terminal. 127 | 4. Relever le challenge dans le dossier `challenge/` : 128 | 5. Vérifier votre travail avec **pytest** : 129 | 130 | ```bash 131 | pytest -v 132 | ``` 133 | 134 | Les tests vous indiqueront si votre solution est correcte. 135 | 136 | ## Important 137 | 138 | - **Aucune réponse n’est donnée** dans les énoncés après les premiers TP. 139 | - **Cherchez par vous-même** avec l'aide des commandes Linux (`--help`, `man`, 140 | etc.). 141 | - **Validez vos résultats** uniquement via les tests automatisés. 142 | - **Si vous bloquez**, n'hésitez pas à demander de l'aide sur 143 | [le discord](https://blog.stephane-robert.info/docs/discord/). 144 | 145 | ## Mise à jour du dépôt 146 | 147 | Je vais continuer à mettre à jour ce dépôt avec de nouveaux exercices et des 148 | améliorations. Pour récupérer les dernières modifications, vous pouvez 149 | simplement exécuter : 150 | 151 | ```bash 152 | git pull origin main 153 | ``` 154 | 155 | ## Contribuer 156 | 157 | Bien entendu, vous êtes invités à contribuer à ce dépôt en proposant des 158 | améliorations ou en corrigeant des erreurs. N'hésitez pas à ouvrir une **issue** 159 | ou à soumettre une **pull request**. 160 | 161 | Plus d'infos [ici](https://github.com/stephrobert/containers-training/blob/main/contributing.md) 162 | 163 | ## Me soutenir 164 | 165 | Si vous appréciez ce travail et souhaitez me soutenir, vous pouvez me payer un 166 | café ☕️: 167 | 168 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/stephanerobert89902) 169 | 170 | ## Copyright et licence 171 | 172 | Tous les contenus contenus dans ce repo sont : 173 | 174 | - Copyright ©2025 Stéphane Robert 175 | - Distribués sous [licence Creative Commons BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) 176 | 177 | ![Creative Commons BY-SA](https://mirrors.creativecommons.org/presskit/buttons/88x31/png/by-sa.png) 178 | -------------------------------------------------------------------------------- /cloud-config.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | users: 3 | - name: ubuntu 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/ubuntu/.profile 17 | content: | 18 | export PATH=$PATH:/home/ubuntu/.local/bin 19 | append: true 20 | runcmd: 21 | - chown -R ubuntu:ubuntu /home/ubuntu 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | pipx install pytest 3 | pipx inject pytest pytest-testinfra 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | pytest-testinfra -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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-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-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-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-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-01-navigation-fichiers/fichier_exercice4.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephrobert/linux-training/e13d2ab97387b8f6533fe9ea173ec069f0afe91f/tp-01-navigation-fichiers/fichier_exercice4.txt -------------------------------------------------------------------------------- /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-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-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 | -------------------------------------------------------------------------------- /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-02-00-commandes-avancees/challenge/utilisateurs.csv: -------------------------------------------------------------------------------- 1 | Alice,30 2 | Bob,25 3 | Charlie,35 4 | Alice,30 5 | Bob,25 -------------------------------------------------------------------------------- /tp-02-00-commandes-avancees/fichiers/exercice3a.txt: -------------------------------------------------------------------------------- 1 | ligne1 2 | ligne2 3 | ligne3 4 | -------------------------------------------------------------------------------- /tp-02-00-commandes-avancees/fichiers/exercice3b.txt: -------------------------------------------------------------------------------- 1 | ligne1 2 | ligneModifiee 3 | ligne3 4 | -------------------------------------------------------------------------------- /tp-02-00-commandes-avancees/fichiers/exercice5.txt: -------------------------------------------------------------------------------- 1 | nom,age 2 | Alice,30 3 | Bob,25 4 | Charlie,35 5 | -------------------------------------------------------------------------------- /tp-02-00-commandes-avancees/fichiers/exercice5a.txt: -------------------------------------------------------------------------------- 1 | 1 Alice 2 | 2 Bob 3 | 3 Charlie 4 | -------------------------------------------------------------------------------- /tp-02-00-commandes-avancees/fichiers/exercice5b.txt: -------------------------------------------------------------------------------- 1 | 1 ALICIA 2 | 2 ROBERT 3 | 4 DENIS 4 | -------------------------------------------------------------------------------- /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-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-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 | -------------------------------------------------------------------------------- /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-01-xargs/fichiers/fichiers_avec_espaces.txt: -------------------------------------------------------------------------------- 1 | "mon fichier 1.txt" 2 | "un autre fichier 2.txt" 3 | -------------------------------------------------------------------------------- /tp-02-01-xargs/fichiers/liste_fichiers.txt: -------------------------------------------------------------------------------- 1 | fichiers/exemples1.txt 2 | fichiers/exemples2.txt 3 | -------------------------------------------------------------------------------- /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-02-sed/fichiers/apache.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerAdmin webmaster@localhost 3 | DocumentRoot /var/www/html 4 | 5 | OtherConfig On 6 | -------------------------------------------------------------------------------- /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-02-sed/fichiers/report.csv: -------------------------------------------------------------------------------- 1 | Date,Utilisateur,Action 2 | 2024-05-01,alice,connexion 3 | 2024-05-01,bob,deconnexion 4 | -------------------------------------------------------------------------------- /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-02-02-sed/modifs.sed: -------------------------------------------------------------------------------- 1 | s/admin/root/g 2 | /^#/d 3 | 1i\# Liste des utilisateurs 4 | -------------------------------------------------------------------------------- /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-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-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-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-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-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/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-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-02-03-awk/fichiers/ventes.csv: -------------------------------------------------------------------------------- 1 | Produit,Montant 2 | Stylo,2.5 3 | Cahier,4.0 4 | Clé USB,9.99 -------------------------------------------------------------------------------- /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-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-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-04-find/fichiers/ancien.log: -------------------------------------------------------------------------------- 1 | Ancien log 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-04-find/fichiers/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo 'Script exécuté' 3 | -------------------------------------------------------------------------------- /tp-02-04-find/fichiers/secret.txt: -------------------------------------------------------------------------------- 1 | Top secret 2 | -------------------------------------------------------------------------------- /tp-02-04-find/fichiers/vide.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephrobert/linux-training/e13d2ab97387b8f6533fe9ea173ec069f0afe91f/tp-02-04-find/fichiers/vide.txt -------------------------------------------------------------------------------- /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-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-03-premiers-scripts-shell/challenge/majeurs.txt: -------------------------------------------------------------------------------- 1 | Alice 2 | Bob 3 | Stephane 4 | -------------------------------------------------------------------------------- /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-03-premiers-scripts-shell/challenge/utilisateurs.csv: -------------------------------------------------------------------------------- 1 | nom,age 2 | Alice,22 3 | Bob,35 4 | Charlie,17 5 | Stephane,57 -------------------------------------------------------------------------------- /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-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-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-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-06-acl/challenge/document1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephrobert/linux-training/e13d2ab97387b8f6533fe9ea173ec069f0afe91f/tp-06-acl/challenge/document1.txt -------------------------------------------------------------------------------- /tp-06-acl/challenge/document2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephrobert/linux-training/e13d2ab97387b8f6533fe9ea173ec069f0afe91f/tp-06-acl/challenge/document2.txt -------------------------------------------------------------------------------- /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-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-06-acl/fichiers/partage/nouveau_fichier.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephrobert/linux-training/e13d2ab97387b8f6533fe9ea173ec069f0afe91f/tp-06-acl/fichiers/partage/nouveau_fichier.txt -------------------------------------------------------------------------------- /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-07-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 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:ubuntu/24.04/cloud tp --config=cloud-init.user-data="$(cat cloud-config.yaml)" 28 | incus alias add login 'exec @ARGS@ -- su -l ubuntu' 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éé une instance Ubuntu 24.04 sur laquelle est installé 33 | les packages néessaires 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 | 3. Vérifiez que le cache est vidé. 130 | 131 | 👉 **Explication** : `apt clean` supprime tous les fichiers `.deb` téléchargés, 132 | utile pour libérer de l'espace disque. 133 | 134 | ### Exercice 4 : Explorer un paquet 135 | 136 | * **Action** : 137 | 138 | 1. Utilisez `apt search` pour trouver le package install le serveur ssh. 139 | 2. Affichez ses détails avec : 140 | 141 | ```bash 142 | apt show 143 | ``` 144 | 145 | 👉 **Explication** : `search` parcourt la base locale des paquets et `show` 146 | affiche toutes les infos : dépendances, description, etc. 147 | 148 | ### Exercice 5 : Ajouter un dépôt et mettre à jour 149 | 150 | * **Action** : 151 | 152 | 1. Editez le fichier dans `/etc/apt/sources.list.d/docker.list` : 153 | 154 | ```bash 155 | sudo vi /etc/apt/sources.list.d/docker.list 156 | ``` 157 | 2. Ajoutez la ligne suivante : 158 | 159 | ```bash 160 | deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable 161 | ``` 162 | 163 | 3. Ajoutez la clé GPG : 164 | 165 | ```bash 166 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc 167 | sudo chmod a+r /etc/apt/keyrings/docker.asc 168 | ``` 169 | 170 | 4. Mettez à jour la liste des paquets : 171 | 172 | ```bash 173 | sudo apt update 174 | ``` 175 | 5. Installez le paquet `docker-ce` : 176 | 177 | ```bash 178 | sudo apt install docker-ce 179 | ``` 180 | 181 | 👉 **Explication** : APT détecte automatiquement les nouveaux dépôts ajoutés 182 | dans `sources.list.d`. La clé GPG assure l'intégrité des paquets et la sécurité 183 | de l'installation. La commande `apt update` met à jour la liste des paquets 184 | disponibles, y compris ceux du dépôt Docker. L'installation de `docker-ce` 185 | permet d'utiliser Docker sur votre système. Vous pouvez vérifier son 186 | installation avec : 187 | 188 | ```bash 189 | docker --version 190 | ``` 191 | 192 | --- 193 | 194 | ## 🚀 Challenge à valider 195 | 196 | 📂 Rendez-vous dans le dossier [`challenge/`](./challenge/README.md) pour 197 | découvrir votre mission finale ! 198 | 199 | --- 200 | 201 | # ✅ Bon courage et amusez-vous avec APT 😄 202 | -------------------------------------------------------------------------------- /tp-07-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-07-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 | --------------------------------------------------------------------------------