Console et manipulation de fichiers

Partie 1 / Chapitre 2 : Console et manipulation de fichiers

Dans ce nouveau chapitre de notre formation à Linux et au Bash, nous allons entrer un peu plus dans le vif du sujet. Au-delà des concepts théoriques et de la philosophie, Linux propose un environnement de travail en ligne de commande permettant de manipuler le système de fichiers, les flux, et les utilisateurs et groupes.

Pour commencer, nous allons voir :

  • Les shells sous Linux, qui sont des langages utilisables depuis le terminal ;
  • Le système de fichiers ;
  • Les commandes de base utilisables dans le terminal (ou CLI) ; et enfin,
  • Le fichier pour configurer son shell.

POSIX et compatibilité des systèmes Unix

Avant de parler de Shells, il faut d’abord introduire POSIX, « le » standard qui garantit la portabilité des programmes développés sur un système compatible Unix vers un autre système Unix.

Unix, c’est la base sur laquelle reposent les distributions Linux, mais aussi Mac OS ou BSD. Sans rentrer dans les détails, c’est en quelque sorte le noyau commun à tous ces systèmes d’exploitation : ils partagent la même base et divergent ensuite dans leurs particularités propres. Vous pouvez vraiment voir cela comme le noyau d’un fruit.

image

Les différents shells

Le Shell est « le » langage de programmation de base du système d’exploitation : il est conçu pour permettre de communiquer avec le système d’exploitation, que ce soit en ligne de commande (ou CLI) ou via des scripts.

Le plus basique, et systématiquement disponible sur tout système Unix, c’est «sh ». Il fournit les commandes et la structure de base du langage. Mais si nous disons « les shells » dans le titre, c’est qu’à partir de sh ont hérité plusieurs shells différents, apportant de nombreuses fonctionnalités facilitant la vie des développeurs. À noter que mentionner sh malgré l’existence de ces autres shells n’est pas non plus anodin : lorsque nous travaillons dans des environnements très hétérogènes, nous pouvons être amenés à viser la compatibilité avec sh dans nos scripts, car cela garantit la portabilité de nos scripts à peu près sur n’importe quel système POSIX.

Bash est un shell déjà plus avancé, mais encore standard sur la plupart des distributions Linux. Il apporte un paquet de fonctionnalités sympathiques pour l’utilisation en ligne de commande (comme l’auto-complétion), ou des structures de données plus avancées pour l’utilisation dans les scripts. C’est de fait le shell recommandé pour l’écriture des scripts d’automatisation.

Pour des usages plus avancés, surtout dans le terminal, on a des shells beaucoup plus élaborés, qui apportent de nombreuses options de personnalisation, de coloration syntaxique, de l’auto-complétion avancée, etc. Parmi eux, nous pouvons mentionner :

  • Zsh (mon favori perso) est parfois proposé par défaut sous Mac OS et offre de nombreuses améliorations, par rapport à Bash, pour l’expérience utilisateur dans le terminal ;
  • Fish (aussi très plébiscité, mais pas totalement compatible POSIX) offre une expérience utilisateur immersive, avec des suggestions automatiques, une configuration web et une syntaxe particulièrement lisible ;
  • Nushell est plus spécialisé, principalement pour les flux de données structurées (comme les tableaux ou JSON).

image

Le système de fichiers

C’est un autre concept de base à comprendre, quand on prend en main Linux. La base est similaire à ce qu’on retrouve sur n’importe quel autre système, comme Windows ou Mac OS : une arborescence de dossiers, avec des fichiers dedans. Comme nous l’avons déjà vu en introduction, le système de fichiers Unix a toutefois ses particularités. Notamment, tout est fichier et tout est traité comme un fichier.

Le système de fichiers sous Linux commence par le dossier racine «/» qui contient tout le reste de l’arborescence. Celle-ci contient ensuite un ensemble de fichiers de base du système.

Quelques-uns sont particulièrement importants à connaître, quand on débute.

  • /home car c’est par là que nous commençons, lorsqu’on crée notre compte sous Linux. Nous y retrouvons le dossier personnel de chaque utilisateur, où il stocke ses fichiers. L’administrateur est le seul à faire bande à part, avec son propre dossier à la racine du système : /root.
  • /media et /mnt reviennent dès que nous utilisons des périphériques (mais les gestionnaires de fichiers sous Linux cachent cette notion). Ce sont les points de montage pour les médias amovibles comme les USB ou CD (/media) et pour les systèmes de fichiers externes (/mnt).
  • /etc, /bin (et /sbin) et /opt contiennent tous les fichiers relatifs aux programmes que nous installons et configurons sur notre système. /bin et /sbin contiennent les binaires essentiels au fonctionnement du système (/sbin ceux réservés à l’administration), et /etc contient les fichiers de configuration de ces programmes. /opt n’est pas toujours utilisé, mais quand nous déployons une application à la main (et ça peut inclure notre propre application), ou des variants de programmes standard, nous utilisons souvent ce dossier.
  • et enfin, /var contient les données variables comme les logs (/var/log/) ou les caches, qui changent pendant l’exécution. Les logs sont particulièrement importants car si un programme plante, c’est l’endroit où nous retrouverons ses derniers messages générés avant le crash. À noter également que les données de sites web sont souvent installées par défaut dans le dossier /var/www/ par des applications comme NginX et Apache (connus pour leurs fonctionnalités de serveur web).

Afin d’être complet, nous vous proposons ci-dessous une liste avec les autres dossiers standard utiles à connaître.

  • /boot : Stocke les fichiers nécessaires au démarrage du système, comme le noyau et les chargeurs de boot.
  • /sys : Système de fichiers virtuel exposant des informations sur le noyau et les pilotes.
  • /lib et /lib64 : Bibliothèques partagées essentielles pour les binaires du système (et variante 64 bits).
  • /proc : Système de fichiers virtuel fournissant des informations sur les processus et le noyau.
  • /dev : Répertoire des fichiers spéciaux représentant les périphériques matériels et virtuels (on y retrouve des fichiers spéciaux représentant les périphériques matériel, ce qui inclut les disques durs et clés USB avant montage, mais aussi la souris, le clavier, l’écran, etc.).
  • /run : Données temporaires runtime pour les processus en cours d’exécution. Certains systèmes proposent aussi /srv pour certains services, mais il est peu ou pas utilisé.
  • /usr : Hiérarchie secondaire pour les programmes et données utilisateur non critiques au boot.
  • /tmp : Stockage de fichiers temporaires effacés au redémarrage.

CLI : les commandes de base

Il existe de nombreuses catégories de commandes de base, mais nous allons nous concentrer sur celles bien pratiques pour débuter.

Navigation

Puisque nous avons parlé du système de fichiers, les premières commandes à voir (ou rappeler), ce sont les commandes permettant de naviguer dedans. On y retrouve cd(change directory), ls (lister), cat (lire), et tail (pour afficher une partie du fichier). tail possède un paramètre très intéressant, pour lire les logs : on peut l’invoquer comme tail -f pour qu’il reste ouvert et continue d’afficher tout contenu qui s’ajouterait au fichier après l’ouverture. C’est excellent pour les logs, car lorsqu’un programme est en cours d’exécution, et qu’il est sollicité, il va mettre à jour ce fichier avec les nouvelles informations. Nous pouvons également mentionner which qui permet de retrouver le chemin d’accès à un exécutable.

Gestion des droits

C’est un point particulièrement important pour la sécurité. Sous Linux, nous pouvons définir des groupes et des utilisateurs, puis leur définir des droits de lecture, d’écriture et d’exécution sur les fichiers et dossiers du système. Typiquement, les services que nous utilisons sous Linux utilisent des « utilisateurs » qui leur sont dédiés. De la sorte, un service donné ne peut manipuler que les fichiers qui lui sont alloués, et personne d’autre que lui ne peut les manipuler. Cela dépend bien entendu des droits configurés sur des fichiers et dossiers. Par exemple, un dossier qui est ouvert à tous en lecture sera accessible à n’importe qui, mais les fichiers qu’il contient peuvent n’être accessibles en écriture et à l’exécution qu’à leur propriétaire.

Un compte un peu particulier est le compte root. Celui-ci a par défaut accès à l’intégralité du système et ne doit être utilisé que pour les actions système (et seul ce compte devrait être autorisé à réaliser ces actions). Pour faciliter l’administration sous Linux, nous disposons également de ce que nous appelons une élévation de privilège (temporaire ou permanente), qu’on obtient avec la commande sudo -i. Celle-ci ne peut être exécutée que par des utilisateurs triés sur le volet (dont le nom figure dans un fichier spécial « sudoers » qui ne peut être manipulé que par root ou un compte qui est déjà dedans).

À noter qu’il est également recommandé d’utiliser la commande sudo en combinaison directement avec la commande à exécuter en tant que root. De la sorte, l’élévation de privilège ne dure que le temps de l’exécution de cette commande, elle n’est pas permanente.

Pour manipuler les droits, nous avons notamment chmod (assigner des droits à un utilisateur et un groupe donné), et chown (pour changer le propriétaire d’un fichier donné). La manipulation des droits se fait soit par l’initial du droit correspondant (read, write, execute), soit en binaire : 100 (4) pour la lecture, 010 (2) pour l’écriture, et 001 (1) pour l’exécution. Un fichier sur lequel nous disposons de tous les droits aura donc le chiffre 7 (111), tandis qu’un droit de lecture et écriture aura le chiffre 6 (110). Promis, nous n’irons pas plus loin dans l’algèbre de Boole (en tout cas pas dans ce cours).

image

Compression et décompression de fichier

Pour finir sur les commandes, celles permettant de compresser et décompresser des fichiers deviennent incontournables, dès qu’il s’agit de partager un ensemble de fichiers d’un système vers un autre. Les deux technologies les plus utilisées sont les suivantes :

  • zip et unzip permettent de générer des fichiers « zip » qui peuvent être facilement décompressés sur n’importe quel système (y compris Windows). Les deux s’utilisent sans argument, en passant en paramètre l’endroit où créer l’archive (plus la liste des fichiers à compresser pour zip).
  • tar est une commande polyvalente, car elle permet de sélectionner divers modes de compressions. Pour nous simplifier la tâche, nous pouvons partir de tar -cvf (pour compresser) et tar -xvf (pour décompresser). On manipule alors une archive avec l’extension tar.gz.

Les variables d’environnement

Ce sont des variables qui seront utilisées par le système et certains outils en ligne de commande comme éléments de configuration et constantes globales du système. Leur nombre est variable, mais il en existe un certain nombre de standards. Ici, nous n’allons pas toutes les voir, mais juste l’essentiel pour débuter :

  • SHELL fournit le nom du shell actuellement utilisé.
  • PATH est une variable particulièrement importante, car elle contient tous les endroits où notre shell ira chercher les exécutables à sa disposition. On la surcharge souvent avec des dossiers personnels, comme un dossier /bindans son dossier personnel. Dans ces cas-là, il est important de bien conserver et ajouter le nouveau chemin à l’existant. On écrira par exemple PATH="${PATH}:/home/meier-link/bin" pour que les exécutables dans /home/meier-link/bin surchargent ceux du système (s’il y en a plusieurs du même nom, celui dans notre dossier personnel remplace celui du système) ou bien PATH="/home/meier-link/bin:${PATH}"si on veut en priorité préserver les exécutables du système.
  • HOME contient le chemin vers le dossier personnel du compte avec lequel nous sommes connecté. Donc si mon compte s’appelle « meier-link », mon dossier HOME aura pour valeur /home/meier-link. Pour les applications qui ont un utilisateur, mais pas de vrai compte, cette variable sera vide. Et pour le compte root ? Si vous avez suivi jusque là, vous pouvez deviner que vaudra son HOME.
  • USER contient le nom de l’utilisateur actuel.
  • PWD contient le chemin d’où s’exécute actuellement le script (cela vaut également pour Bash et zsh).
  • LANG et/ou LANGUAGE donnent la langue actuellement configurée pour le système.

Le fichier de configuration du shell

Pour terminer cette partie, il est important de mentionner un fichier très utile, quand nous sommes amené à passer une partie de notre vie dans un terminal. Je parle bien entendu du fichier .bashrc (ou .zshrc pour zsh). Le « rd » à la fin du nom du fichier signifie « run commands » et dans les faits, ce script sera exécuté par le terminal à son ouverture. Et en shell, déclarer une variable, définir une fonction, un bloc conditionnel ou une boucle, c’est écrire des commandes. Donc toutes les commandes que nous ajoutons à ce fichier vont affecter le comportement du terminal. Nous n’allons pas nous attarder sur le scripting Bash tout de suite, une section dédiée va suivre. À noter quand même quelques règles utiles spécifiquement pour le fichier rc :

  • On peut définir des alias de commande Bash avec alias, et unalias pour annuler. Par exemple, on retrouve souvent par défaut alias ll="ls -l" car l’option -l fournit des informations complémentaires très utiles.
  • Si on veut qu’une variable définie (ou surchargée) dans le fichier rc soit bien disponible par la suite, il faut bien préciser export. Par exemple, pour ajouter OpenCode à mon terminal, j’ai utilisé export PATH=/home/meier-link/.opencode/bin:${PATH}(vous noterez que je n’ai pas mis de “guillemets” ? C’est parce que pour les chaînes de caractères en Bash, c’est optionnel… Je reviendrai là dessus en parlant de scripting).

Exercices

Exercice 0

Dans le passage sur les variables d’environnement, pour le HOME, avez-vous deviné quel sera sa valeur, pour le compte root ?

Exercice 1

Débutant

Une IA vous donne cette commande pour lister les fichiers, mais vous ne voyez pas les fichiers de configuration (comme .bashrc) : ls Documents. Que manque-t-il ?

Exercice n°2

Débutant

Vous voulez créer un dossier “Projet” et un fichier “note.txt” à l’intérieur en une seule fois. L’IA propose : mkdir Projet; touch note.txt. Quel est le problème ?

Exercice n°3

Débutant

Quelle est la différence entre un chemin relatif et un chemin absolu ?

Exercice n°4

Confirmé

L’IA vous suggère d’ajouter alias ll="ls -l" dans votre terminal. Où devez-vous écrire cette ligne pour qu’elle soit disponible à chaque redémarrage ?

Exercice n°5

Confirmé

Vous avez un script install.sh. L’IA vous dit de le lancer avec ./install.sh, mais vous recevez une erreur « Permission denied ». Quelle commande a été oubliée ?

Exercice n°6

Confirmé

L’IA vous propose de déplacer un dossier avec cp -r dossier_orig dossier_dest; rm -rf dossier_orig. Existe-t-il une commande plus simple et plus sûre ?

Exercice n°7

Avancé

Vous modifiez votre .bashrc pour ajouter un chemin au PATH, mais le changement n’est pas pris en compte immédiatement. Quelle commande permet de recharger la configuration sans fermer le terminal ?

Exercice n°8

Avancé

Une IA vous propose cette commande : export PATH=/ma/nouvelle/app. Pourquoi est-ce extrêmement dangereux pour la survie de votre session de terminal ?

Exercice n°9

Avancé

Quelle est la différence fondamentale entre sh et bash lors de l’écriture d’un script ?

Exercice n°10

Expert

Un script généré par l’IA contient rm -rf /home/user/ projet/temp. Remarquez-vous l’erreur subtile qui pourrait effacer tout votre dossier personnel ?

Exercice n°11

Expert

Pourquoi est-il recommandé d’utiliser des guillemets autour des variables en Bash, même si c’est parfois optionnel ?

Exercice n°12

Expert

Comment créer un lien symbolique vers un fichier pour qu’il soit accessible depuis un autre dossier sans le copier ?


Ne manque-t-il pas le meilleur ?

Dans ce chapitre, nous avons exploré le point d’entrée de notre console, le shell, et les principales commandes pour manipuler les fichiers. Nous avons également vu les variables d’environnement, qui sont utilisées par les outils en ligne de commande, mais aussi comment configurer notre shell.

Si vous vous rappelez le chapitre d’introduction, il y a une partie que nous n’avons pas encore vu : le dataflow. Comme c’est un morceau assez conséquent, nous l’avons gardé pour un chapitre dédié, qui se trouve être le suivant : La manipulation du dataflow.


Réponses aux exercices

  1. Pour le compte root, $HOME vaudra… /root !

  2. Niveau débutant

    1. Il manque l’option -a (ou -all) pour afficher les fichiers cachés (ceux commençant par un point). La commande devrait être ls -a Documents.
  3. Niveau débutant

    1. La commande touch va créer le fichier dans le répertoire courant, pas à l’intérieur du dossier « Projet ». Il faudrait faire mkdir Projet; touch Projet/note.txt ou cd Projet; touch note.txt.
  4. Niveau débutant

    1. Un chemin absolu part de la racine (/) du système (ex. : /home/user/doc), tandis qu’un chemin relatif part du dossier où l’on se trouve actuellement (ex. : Documents/doc).
  5. Niveau confirmé

    1. Dans le fichier de configuration de votre shell, généralement le fichier caché .bashrc situé dans votre répertoire personnel (HOME).
  6. Niveau confirmé

    1. Il faut donner les droits d’exécution au fichier avec la commande chmod +x install.sh.
  7. Niveau confirmé

    1. Oui, la commande mv dossier_orig dossier_dest, qui déplace ou renomme les fichiers et dossiers en une seule étape.
  8. Niveau avancé

    1. La commande source .bashrc (ou . .bashrc).
  9. Niveau avancé

    1. Car elle écrase la variable PATH au lieu de lui ajouter un chemin. Vous perdrez l’accès à toutes les commandes de base (ls, cd, etc.). Il faut utiliser export PATH=/ma/nouvelle/app:${PATH}.
  10. Niveau avancé

    1. sh est le shell basique visant la compatibilité POSIX (portabilité maximale), tandis que bash est plus avancé et offre des fonctionnalités comme l’auto-complétion et des structures de données complexes facilitant l’automatisation.
  11. Niveau expert

    1. L’espace entre user/ et projet/temp fait que la commande reçoit deux arguments distincts : elle va essayer de supprimer /home/user/ ET projet/temp. C’est une erreur de rigueur d’écriture typique d’une IA ou d’une saisie approximative.
  12. Niveau expert

    1. Pour éviter que le shell n’interprète les espaces ou les caractères spéciaux contenus dans la valeur de la variable comme des séparateurs de commande ou des wildcards.
  13. Niveau expert

    1. Nous utilisons la commande ln -s source nom-lien. (nom-lien devrait être le chemin complet du lien que nous voulons créer, ça évite les ambiguïtés lorsque nous voulons vérifier où pointe le lien symbolique après coup).
Write a comment
No comments yet.