Linux LPIC-1 (101-500) #2 – Edition de fichiers et ligne de commande

Edition de fichiers
Nano
nano
c’est un peu l’équivalent de notepad.exe
sous Windows : il est simple d’usage, pas très puissant et, omniprésent.
nano
présente une interface simple et épurée qui lui permet de s’afficher correctement même avec une résolution limitée (t’as connu les écrans cathodiques 14 » avec une résolution de 640×480 ?).

Les raccourcis clavier sont affichés en bas de l’écran, plus l’écran est large plus il y en a qui s’affichent. Ils peuvent paraître cryptiques pendant 30 ou 40 secondes : mais pourquoi les raccourcis commencent par un accent circonflexe ?!
Ca ne s’invente peut-être pas mais ça correspond à Ctrl. Pour capter, fais un Ctrl + c dans un shell (ça permet d’arrêter l’exécution d’une commande, et ça fonctionnera même si tu n’as pas de commande en cours).
D’autre part, les raccourcis sont inscrits en majuscule mais sont insensibles à la casse.
L’exemple ci-dessous a été réalisé par un cascadeur
professionnelun peu naze, ne pas tenter de reproduire.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Dec 18 03:34:13 2024 from 10.0.0.2
root@debian:~# rm -rf /^C
root@debian:~#
Ctrl + c a été lancé (ligne 4) et le prompt est revenu vide à la ligne suivante.
Certains raccourcis utilisent Alt, dans ce cas ils sont préfixé, non plus de ^, mais de M (je sais pas, c’est peut-être pour meta ?).
Lorsque l’on quitte nano
, avec Ctrl + x, il nous est proposé de nommer le fichier. Si tu éditais un fichier, tu valides par entrée si tu souhaites écrire dans le fichier initial ou, tu changes le nom si tu souhaites en faire un nouveau.
nano
offre la possibilité d’ouvrir plusieurs fichiers avec Ctrl + r. Par défaut, il va insérer le contenu du second fichier dans le premier mais tu peux lui demander spécifiquement de l’ouvrir dans un autre tampon (buffer) à l’aide de Alt + f.
On naviguera entre les tampons à l’aide de Alt + < et Alt + >.
Si tu souhaites créer un nouveau fichier vide dans cet autre tampon, il ne faudra pas le nommer lors de la commande Ctrl + r, Alt + f. nano
va de facto créer un fichier vide dans un nouveau buffer. Tu pourras le nommer à l’enregistrement.
Ctrl + k permet de couper, par défaut il coupera la ligne entière qui entrera alors dans le presse-papier pour être collée ailleurs. Mais on peut faire des opérations plus précises en marquant une région : on positionne le curseur au début de la région à marquer puis on presse Alt + a et on se déplace avec les flèches vers la fin de la zone souhaitée (on peut sélectionner ainsi plusieurs lignes) et là on peut couper avec Ctrl + k.
Je ne sais pas trop ce qui est passé par la tête des dévs mais, pour copier il faut utiliser Alt + ^. Non non ! Pas celui à gauche de P ; celui du Alt gr + ç. Ca donne pour copier (une fois la région sélectionnée) : Alt + Alt gr + ç.
Pour rechercher et remplacer du texte, dans nano
on utilisera les raccourcis :
- Ctrl + w pour rechercher simplement (la recherche est insensible à la casse), on pourra lancer le même raccourci et valider par entrée (
nano
conserve le terme rechercher sauf si on tape un nouveau) ou Alt + w pour t’éviter de valider de nouveau. Attention, la recherche bouclera dans le fichier après être arrivée à la fin (juste au dessus de la liste des raccourcis en bas de l’écran). - Ctrl + \ (encore une purge à taper sur nos claviers AZERTY) et Alt + r permettent de rechercher-remplacer (la recherche accepte les expressions régulières avec Alt + r… oué oué encore une fois… j’adore
nano
). On donne alors le terme recherché et ce par quoi on veut le remplacer.nano
va nous positionner sur chacune des instances pour nous demander si on remplace sauf si on lui répond A pour toutes les instances du terme recherché.
Vim
Sur une machine installée avec le minimum de paquet, vi
sera fort probablement installé mais pas vim
(Vi IMproved
) donc apt install vim
. Lorsqu’il est installé, il répondra aux deux noms lorsque l’on souhaite l’ouvrir alors on ne parlera plus que de vi
… vim
est très austère déroutant de prime abord parce que son mode par défaut, le mode normal, ne permet pas de modifier.
C’est loin d’être l’éditeur de texte le plus intuitif… Il faudra consacrer un peu de temps pour réussir à l’utiliser sans réfléchir, même pour les tâches du quotidien. Mais après quelques jours d’utilisation, tu t’en sorts très bien et tu commences à toucher du doigt sa puissance.
Je t’invite encore une fois à lire l’excellent Vim pour les humains – oué je sais, je te l’ai déjà dit dans le précédent chapitre mais comme tu l’as pas lu entre temps – du coup je vais te donner quelques raccourcis clavier pour t’en sortir vite fait parce que là c’est pour toi que je l’écris, pas pour moi :
- échap te permet de revenir au mode normal/commande,
- i mode insertion (là où ton curseur se trouve),
- a mode ajout (après la position de ton curseur),
- y pour yank (l’arrachement) te permet de copier un mot et yy te permet de copier une ligne,
- cw pour cut word,
- u pour undo (annuler),
- dd pour supprimer une ligne (5dd pour supprimer 5 lignes ou 19-22dd pour supprimer les lignes 19 à 22),
- p pour paste (coller), P pour coller à la ligne du dessus,
- / pour rechercher (puis n et N pour rechercher les autres occurrences en avant et en arrière),
- o pour ajouter une ligne en dessous et O pour l’ajouter au dessus.
- : pour lancer une commande.
- :w pour enregistrer,
- :q pour quitter,
- :q! pour quitter sans enregistrer,
- :wq pour enregistrer et quitter (plus rapide : x),
- :3 pour te rendre à la ligne 3,
- Pour rechercher et remplacer en voulant vérifier un truc j’ai trouvé cet article là, ça te plaira.
La ligne de commande
Personnaliser Bash
La personnalisation de Bash
est gérée à deux niveaux : globalement pour le système et localement pour l’utilisateur.
Au niveau du système cela se passe dans le fichier /etc/bash.bashrc
et le dossier /etc/profile.d/
mais voyons plutôt ce qu’il se passe au niveau de l’utilisateur.
Par défaut, ls
n’affiche pas les dotfiles ; ces fichiers de configuration dont le nom commence par un point. On peut néanmoins lui demander de les afficher spécifique à l’aide de l’argument all tel que ls -a
. Dans ton dossier personnel, trois fichiers de configuration vont nous intéresser : .bash_history
, .bashrc
, et, .profile
.

Le premier, .bash_history
, contient l’historique des commandes lancées et l’on peut y accéder directement à l’aide de la commande history
. Je ne sais pas si on y reviendra alors je te précise que tu peux faire une recherche dans ton historique à l’aide de Ctrl + r, il faudra taper une chaîne significative pour retrouver la ou les occurrences de cette chaîne dans les commandes. Si le premier résultat trouvé n’est pas le bon, tu peux appuyer de nouveau sur Ctrl + r pour revenir plus en arrière.
.bashrc
a un rôle bien plus important. C’est notamment là que l’on va pouvoir agir sur la manière dont l’historique est enregistré (longueur d’historique enregistrée par exemple), vérifier que le shell est en couleur, définir le prompt (root@debian:/arbo/rescence/ comme dans la copie d’écran ci-dessus) et même, des alias de commandes et des fonctions.
.profile
va (notamment) charger le fichier .bashrc
pour les sessions de shell interactives.
Revenons sur .bashrc
, les alias
et les fonctions
. Tu as du remarquer que selon le système sur lequel tu es ou l’utilisateur que utilises, ls
n’est pas toujours coloré ? C’est normal : certains systèmes génèrent des alias activés par défaut dont celui de ls
afin qu’ils te paraissent colorés par défaut.
[...]
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
#alias grep='grep --color=auto'
#alias fgrep='fgrep --color=auto'
#alias egrep='egrep --color=auto'
fi
[...]
Mais tu peux tout à fait créer tes propres alias.
[...]
alias radio404='cvlc https://www.radioking.fr/play/radio404 --intf=rc'
alias tambouille='cvlc https://lagrossetambouille.com/flux --intf=rc'
[...]
Et même des fonctions et là je reprends directement celle du cours dans mon .bashrc
pour l’ajouter directement après mes alias.
antoine@dressing:~$ vi ~/.bashrc
[...]
alias radio404='cvlc https://www.radioking.fr/play/radio404 --intf=rc'
alias tambouille='cvlc https://lagrossetambouille.com/flux --intf=rc'
cheat() { curl "https://cheat.sh/$1"; }
[...]
Ok c’est parti, j’enregistre et je lance !
antoine@dressing:~$ cheat iptables
bash: cheat : commande introuvable
antoine@dressing:~$ ah merde
bash: ah : commande introuvable
# Il faut recharger le fichier .bashrc
antoine@dressing:~$ source .bashrc
antoine@dressing:~$ cheat iptables
cheat:iptables
---
tags: [ networking ]
---
# To show hit for rules with auto refresh:
watch --interval 0 'iptables -nvL | grep -v "0 0"'
# To show hit for rule with auto refresh and highlight any changes since the last refresh:
watch -d -n 2 iptables -nvL
# To block port 902 and hide this port from nmap:
iptables -A INPUT -i eth0 -p tcp --dport 902 -j REJECT --reject-with icmp-port-unreachable
[...]
On peut également définir des variables dans notre .bashrc
qui seront chargées automatiquement lors de l’ouverture de sessions shell.
[...]
alias radio404='cvlc https://www.radioking.fr/play/radio404 --intf=rc'
alias tambouille='cvlc https://lagrossetambouille.com/flux --intf=rc'
cheat() { curl "https://cheat.sh/$1"; }
BALAISE="un gros noob"
[...]
antoine@dressing:~$ source .bashrc
antoine@dressing:~$ echo "Regarde comme je suis $BALAISE"
Regarde comme je suis un gros noob
La variable $BALAISE n’est accessible que dans mon shell Bash
. Si je souhaite que les processus enfants de mon shell (scripts, sous-shell, programmes) il faudra que je la précède de la mention export
(ou que je le fasse en deux lignes).
A titre personnel, je profite de mon .bashrc
pour lancer mon script de chargement de ma clé privée dans mon agent ssh qui lance à son tour mon gitpuller.sh si la clé n’était pas encore chargée.
Gestion de fichiers
Encore une fois, c’est un point que j’ai déjà traité par le passé. Toutefois, je ne t’y avais pas parlé de deux outils suivants pourtant si pratiques.
head
permet d’afficher à l’écran les 10 premières lignes d’un fichier quand tail
permet d’afficher les 10 dernières. Tout deux prennent le paramètre -n
si l’on souhaite spécifier le nombre de lignes que l’on souhaite afficher.
tail
prend également le paramètre -f
(follow) pour afficher la fin du fichier et toute nouvelle entrée à la fin du fichier. Dans ce cas, tail
reste actif et ne te rends pas la main (il faudra Ctrl + C pour l’arrêter. Tu peux cependant sauter des lignes avec entrée pour t’y retrouver plus facilement, ça ne modifiera pas le contenu du fichier source.
On peut évidemment aller plus loin en commençant d’afficher après n lignes… etc.
Redirection de données avec pipe
On peut être amené à vouloir utiliser la sortie (output) d’une première commande en entrée d’une autre (input). Par défaut, Linux va recevoir l’entrée d’une commande par son entrée standard (stdin) et envoyer le résultat d’une commande vers la sortie standard (stdout).
En séparant une première commande d’une seconde à l’aide du caractère pipe
, on va pouvoir rediriger la sortie standard (stdout) de la première commande vers l’entrée standard (stdin) de la seconde.
commande1 | commande2
Si l’on prend un cas concret, en console dmesg
retourne une quantité de lignes supérieure à la taille de l’écran empêchant de lire la grande majorité des lignes. En redirigeant la sortie de dmesg
vers less
tu pourras parcourir toutes les lignes, aller en avant et arrière et, même faire des recherches.
dmesg | less
Les commandes récentes ont tendance a être compatibles avec l’usage de pipe
mais pour les commandes les plus anciennes ce n’est pas toujours le cas. mkdir
par exemple n’aime pas du tout recevoir une liste de dossier à créer depuis pipe
.
Pour ce genre de cas, tu pourras utiliser xargs
afin d’itérer sur les entrées.
root@debian:~# FOLDERS="toto tata titi"
root@debian:~# echo $FOLDERS | mkdir
mkdir: opérande manquant
#Saisissez « mkdir --help » pour plus d'informations.
root@debian:~# echo $FOLDERS | xargs mkdir
root@debian:~# ls
tata titi toto
root@debian:~# ls -l
total 12
drwxr-xr-x 2 root root 4096 24 déc. 21:25 tata
drwxr-xr-x 2 root root 4096 24 déc. 21:25 titi
drwxr-xr-x 2 root root 4096 24 déc. 21:25 toto
Redirection de données avec Redirects
pipe
permet de rediriger stdout vers une autre commande alors que redirects permet de rediriger ces données vers une destination (fichier ou périphérique). Je redirigeais la sortie de tar
vers un lecteur de bande il y a quelques années mais je n’ai plus de serveur qui traîne dans mon salon alors on va surtout voir les redirections vers des fichiers.
Pour rediriger la sortie d’une commande vers un fichier on utilise le caractère plus grand que. Disons que je veuille enregistrer la date et l’heure dans un fichier texte et le contenu de ma home.
root@debian:~# date > root_home_content.txt
root@debian:~# ls -l > root_home_content.txt
root@debian:~# cat root_home_content.txt
total 12
-rw-r--r-- 1 root root 0 24 déc. 22:05 root_home_content.txt
drwxr-xr-x 2 root root 4096 24 déc. 21:25 tata
drwxr-xr-x 2 root root 4096 24 déc. 21:25 titi
drwxr-xr-x 2 root root 4096 24 déc. 21:25 toto
root@debian:~#
root_home_content.txt contient alors le résultat de la commande ls
mais pas la date : la seconde redirection a écrasé le contenu du fichier. Pour ajouter du contenu dans un fichier sans écraser le contenu déjà présent, on va doubler le plus grand que.
root@debian:~# date > root_home_content.txt
root@debian:~# ls -l >> root_home_content.txt
root@debian:~# cat root_home_content.txt
mar. 24 déc. 2024 22:07:18 CET
total 16
-rw-r--r-- 1 root root 0 24 déc. 22:05 root_home_content.txt
drwxr-xr-x 2 root root 4096 24 déc. 21:25 tata
drwxr-xr-x 2 root root 4096 24 déc. 21:25 titi
drwxr-xr-x 2 root root 4096 24 déc. 21:25 toto
root@debian:~#
Comme tu le vois, le contenu du fichier a changé mais surtout : le contenu initial a été remplacé. Si dans certains cas c’est pratique de remplacer le contenu d’un fichier, c’est pas pour autant toujours idéal.
De même que tu peux rediriger la sortie d’une commande vers un fichier, tu peux rediriger le contenu d’un fichier vers l’entrée d’une commande avec plus petit que.
root@debian:~# sort < root_home_content.txt
drwxr-xr-x 2 root root 4096 24 déc. 21:25 tata
drwxr-xr-x 2 root root 4096 24 déc. 21:25 titi
drwxr-xr-x 2 root root 4096 24 déc. 21:25 toto
mar. 24 déc. 2024 22:07:18 CET
-rw-r--r-- 1 root root 32 24 déc. 22:07 root_home_content.txt
total 16
root@debian:~#
Mais Antoine,
sort
aurai pu fonctionner sans le<
!Oui je sais mais c’était pour l’exemple alors accepte le stp.
Bon j’ai pas de périphérique physique vers lequel je peux rediriger mais j’ai quand même quelque chose pour toi : /dev/null
. C’est un périphérique virtuel qui sert de trou noir pour les sorties de commande.
root@debian:~# ls -l > /dev/null
root@debian:~#
Génial non ? ls
n’a même pas moufté. Bon je déconne, il a un réel intérêt regarde. Si je recherche tous les fichiers de tableur de ma home tout va bien.
antoine@dressing:~$ find ~/ -name *.xls
/home/antoine/Téléchargements/status(1).xls
/home/antoine/Téléchargements/status.xls
antoine@dressing:~$
Mais lorsque je liste tous ceux du disque dur là c’est déjà plus problématique ; ça dépasse même le buffer de mon terminal alors essayer de retrouver mes tableurs dans tous ça, j’te raconte pas l’angoisse.
antoine@dressing:~$ find / -name *.xls
[...]
find: ‘/proc/9275/task/9275/fdinfo’: Permission non accordée
find: ‘/proc/9275/task/9275/ns’: Permission non accordée
find: ‘/proc/9275/task/9285/fd’: Permission non accordée
find: ‘/proc/9275/task/9285/fdinfo’: Permission non accordée
find: ‘/proc/9275/task/9285/ns’: Permission non accordée
find: ‘/proc/9275/task/9286/fd’: Permission non accordée
find: ‘/proc/9275/task/9286/fdinfo’: Permission non accordée
find: ‘/proc/9275/task/9286/ns’: Permission non accordée
find: ‘/proc/9275/task/9287/fd’: Permission non accordée
[...]
Jusqu’ici je t’ai parlé de stdin et de stdout mais il existe également également un canal d’erreur standard : stderr. Et chacun porte un numéro : stdin porte le 0, stdout porte le 1 et, stderr porte le 2.
On va rediriger stderr vers /dev/null
afin de ne plus l’afficher.
antoine@dressing:~$ find / -name *.xls 2>/dev/null
/usr/share/doc/libole-storage-lite-perl/examples/test.xls
/home/antoine/Téléchargements/status(1).xls
/home/antoine/Téléchargements/status.xls
antoine@dressing:~$
Et là c’est bien plus lisible non ?
Filtrage des sorties avec sort
et cut
sort
est pratique mais par défaut il est limité. Lorsque l’on fait une ls -l
que l’on redirige la sortie vers sort
, ce dernier n’a aucune idée que nous, humains, voyons des colonnes parce que le délimiteur est variable. Un coup c’est 1 espace, un coup c’est 2… Bref, il est pas aidé.
antoine@dressing:~$ ls -l | sort -r
total 432
-rw-r--r-- 1 antoine antoine 3736 11 avril 2024 gandi_dns_updater.sh
-rw-r--r-- 1 antoine antoine 355339 20 déc. 17:00 fin_de_la_bande.png
-rw-r--r-- 1 antoine antoine 3282 10 juil. 17:20 test.csv
drwxr-xr-x 9 antoine antoine 4096 9 juil. 12:38 test
drwxr-xr-x 4 antoine antoine 20480 24 déc. 08:10 Téléchargements
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Public
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Musique
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Modèles
drwxr-xr-x 2 antoine antoine 4096 6 nov. 11:16 testparser
drwxr-xr-x 2 antoine antoine 4096 24 déc. 13:31 Vidéos
drwxr-xr-x 2 antoine antoine 4096 24 déc. 13:30 Images
drwxr-xr-x 2 antoine antoine 4096 20 déc. 08:01 Bureau
drwxr-xr-x 16 antoine antoine 4096 27 nov. 14:32 VirtualBox VMs
drwxr-xr-x 10 antoine antoine 4096 24 déc. 13:30 Documents
C’est en fin de compte assez compréhensible : t’as déjà essayé de ranger tes photos en les nommant au format « jour-mois-année » ? Bah les premiers jours de chaque premier mois de chaque année se retrouvent ensemble. Bah là c’est pareil, sort
va agir depuis le début de la ligne jusqu’à la fin et classer de façon alphabétique (inverse dans notre cas avec -r
).
Il va donc falloir préparer un peu notre sortie de ls
pour sort
. On va pouvoir faire ça avec tr
pour trim (tailler) afin de squeeze (remplacer), les espaces par un délimiteur de notre choix. On pourrait utiliser la virgule comme délimiteur mais ça rend notre sortie écran peu lisible. On va plutôt utiliser une tabulation (attention, pour taper une tabulation dans la console, il faudra feinter en utilisant Ctrl + v + Tab).
Maintenant que le séparateur entre les colonnes est fixe, on va indiquer à sort
le délimiteur ainsi que la colonne qui nous intéresse en l’occurrence la 9ème et dernière colonne.
antoine@dressing:~$ ls -l | tr -s " " " " | sort -r -t " " -k 9
drwxr-xr-x 16 antoine antoine 4096 27 nov. 14:32 VirtualBox VMs
drwxr-xr-x 2 antoine antoine 4096 24 déc. 13:31 Vidéos
drwxr-xr-x 2 antoine antoine 4096 6 nov. 11:16 testparser
-rw-r--r-- 1 antoine antoine 3282 10 juil. 17:20 test.csv
drwxr-xr-x 9 antoine antoine 4096 9 juil. 12:38 test
drwxr-xr-x 4 antoine antoine 20480 24 déc. 08:10 Téléchargements
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Public
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Musique
drwxr-xr-x 2 antoine antoine 4096 9 févr. 2024 Modèles
drwxr-xr-x 2 antoine antoine 4096 24 déc. 13:30 Images
-rw-r--r-- 1 antoine antoine 3736 11 avril 2024 gandi_dns_updater.sh
-rw-r--r-- 1 antoine antoine 355339 20 déc. 17:00 fin_de_la_bande.png
drwxr-xr-x 10 antoine antoine 4096 24 déc. 13:30 Documents
drwxr-xr-x 2 antoine antoine 4096 20 déc. 08:01 Bureau
total 432
Alors tu as peut-être déjà vu la limite : mon dossier « VirtualBox VMs » qui a un espace. Mais je vais lâchement l’ignorer… D’ailleurs tu feras attention, dans les commandes ci-dessus mes tabulations sont remplacées par des espaces multiples.
Cette fois-ci, c’est bien classé par ordre alphabétique inverse. Imaginons alors que seules les colonne de nom et de taille m’intéressent à la manière de du
, on utilise alors cut
.
antoine@dressing:~$ ls -l | tr -s " " " " | sort -r -t " " -k 9 | cut -d " " -f 9,5
4096 VirtualBox
4096 Vidéos
4096 testparser
3282 test.csv
4096 test
20480 Téléchargements
4096 Public
4096 Musique
4096 Modèles
4096 Images
3736 gandi_dns_updater.sh
355339 fin_de_la_bande.png
4096 Documents
4096 Bureau
antoine@dressing:~$
T’as remarqué la ligne vide ? C’est la ligne de total de ls
. Elle n’a pas de 5ème et 9ème colonne donc elle est vide. La seconde partie du nom du dossier ‘VirtualBox VMs » a également disparu.
Tu peux aussi parfaitement souhaiter avoir le résultat d’une commande à l’écran mais aussi dans un fichier. Pour ça il suffit de pipe
une commande vers tee
et le nom du fichier souhaité.
antoine@dressing:~$ ls -l | tr -s " " " " | sort -r -t " " -k 9 | cut -d " " -f 9,5 | tee /tmp/ma_home.txt
4096 VirtualBox
4096 Vidéos
4096 testparser
3282 test.csv
4096 test
20480 Téléchargements
4096 Public
4096 Musique
4096 Modèles
4096 Images
3736 gandi_dns_updater.sh
355339 fin_de_la_bande.png
4096 Documents
4096 Bureau
antoine@dressing:~$ cat /tmp/ma_home.txt
4096 VirtualBox
4096 Vidéos
4096 testparser
3282 test.csv
4096 test
20480 Téléchargements
4096 Public
4096 Musique
4096 Modèles
4096 Images
3736 gandi_dns_updater.sh
355339 fin_de_la_bande.png
4096 Documents
4096 Bureau
antoine@dressing:~$
Filtrage des sorties avec grep
grep
(Globally search a Regular Expression and Print) est un outil de recherche utilisant des motifs de type expression régulière (on nommera ça regex ou regexp) comme terme de recherche. grep
peut rechercher autant dans des fichiers que dans la sortie d’une commande.
On peut faire varier le type de motif utilisé par grep
soit en ajoutant un argument, soit en utilisant un alias. Ainsi pour utiliser un motif de type Extended regexp on utilisera au choix egrep
ou grep -E
, pour un motif de chaîne on utilisera fgrep
ou grep -F
ou encore grep
tout simplement (les alias ne sont pas toujours inclus dans les distributions).
Les expressions régulières permettent d’implémenter des motifs identiques quelque soit le système ou le langage de programmation utilisé. Elles permettent de définir des critères très précis et sont très puissantes mais en aucun cas intuitives. Tu pourras te faire une première idée de ce que c’est à l’aide du manuel man 7 regex
(on utilise man 7
parce que regex
n’est pas une commande mais un standard).
Voyons quelques exemples d’usage de grep
. Extrayons d’abord toutes les lignes de gitpuller.sh contenant le mot « local ».
Attention, grep
est sensible à la casse.
antoine@dressing:~/scripts$ cat gitpuller.sh | grep "Local"
antoine@dressing:~/scripts$
antoine@dressing:~/scripts$ cat gitpuller.sh | grep local
local_repository_folder=$HOME"/GIT-LAB/"
REPOS=($(find $local_repository_folder -name ".git" -type d))
local -r progress=${1?"progress is mandatory"}
local -r total=${2?"total elements is mandatory"}
local -r info=${3:-"In progress"}
# function local variables
local progress_segment
local todo_segment
local info_segment=""
local compl_segment=""
local -r progress_ratio=$((progress * 100 / total))
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
local -r todo_segment_size=$((bar_size - progress_segment_size))
Bon c’est pas mal mais le commentaire au milieu me dérange alors on va essayer les regexp et afficher les lignes qui commencent par « local ». Pour cela on va utiliser ^ qui représente le début de ligne (là où $ représente la fin de ligne).
antoine@dressing:~/scripts$ cat gitpuller.sh | egrep "^local"
local_repository_folder=$HOME"/GIT-LAB/"
antoine@dressing:~/scripts$
Et oui, mes autre lignes de définition de variables locales à la fonction ne sont pas en début de ligne mais après un nombre variable d’espaces. On utilisera alors \s pour indiquer un espace et * pour indiquer « peut importe le nombre ».
antoine@dressing:~/scripts$ cat gitpuller.sh | egrep "^\s*local"
local_repository_folder=$HOME"/GIT-LAB/"
local -r progress=${1?"progress is mandatory"}
local -r total=${2?"total elements is mandatory"}
local -r info=${3:-"In progress"}
local progress_segment
local todo_segment
local info_segment=""
local compl_segment=""
local -r progress_ratio=$((progress * 100 / total))
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
local -r todo_segment_size=$((bar_size - progress_segment_size))
antoine@dressing:~/scripts$
Dans gitpuller.sh j’ai défini mes variables internes en majuscules. Je pourrais vouloir les afficher également alors, il va falloir faire un ou (ici le pipe
) entre les lignes qui commencent par local et celles qui sont en majuscules (entre crochet, je donne les lettres de A à Z).
antoine@dressing:~/scripts$ cat gitpuller.sh | egrep "^\s*local|^\s*[A-Z]"
local_repository_folder=$HOME"/GIT-LAB/"
REPOS=($(find $local_repository_folder -name ".git" -type d))
PULL_ITER=${#REPOS[@]}
PROGRESS_BAR_CHAR=(█ ▒)
PROGRESS_BAR_INFO_TEMPLATE=' %s [%2d/%2d] '
PROGRESS_BAR_COMPL_TEMPLATE=' %2d%% '
PROGRESS_BAR_TEMPLATE='\033[1m%s%s\033[0m%s%s\r'
PROGRESS_BAR_DISPLAY_INFO=1
PROGRESS_BAR_DISPLAY_COMPL=1
SECONDS=0
local -r progress=${1?"progress is mandatory"}
local -r total=${2?"total elements is mandatory"}
local -r info=${3:-"In progress"}
local progress_segment
local todo_segment
local info_segment=""
local compl_segment=""
local -r progress_ratio=$((progress * 100 / total))
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
local -r todo_segment_size=$((bar_size - progress_segment_size))
COLUMNS=$(tput cols)
COLUMNS=$(tput cols)
antoine@dressing:~/scripts$
Mais j’aurai pu ne demander que les mots qui commencent par P, R, O, G, E et S.
antoine@dressing:~/scripts$ cat gitpuller.sh | egrep "^\s*local|^\s*[P,R,O,G,E,S]"
local_repository_folder=$HOME"/GIT-LAB/"
REPOS=($(find $local_repository_folder -name ".git" -type d))
PULL_ITER=${#REPOS[@]}
PROGRESS_BAR_CHAR=(█ ▒)
PROGRESS_BAR_INFO_TEMPLATE=' %s [%2d/%2d] '
PROGRESS_BAR_COMPL_TEMPLATE=' %2d%% '
PROGRESS_BAR_TEMPLATE='\033[1m%s%s\033[0m%s%s\r'
PROGRESS_BAR_DISPLAY_INFO=1
PROGRESS_BAR_DISPLAY_COMPL=1
SECONDS=0
local -r progress=${1?"progress is mandatory"}
local -r total=${2?"total elements is mandatory"}
local -r info=${3:-"In progress"}
local progress_segment
local todo_segment
local info_segment=""
local compl_segment=""
local -r progress_ratio=$((progress * 100 / total))
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
local -r todo_segment_size=$((bar_size - progress_segment_size))
antoine@dressing:~/scripts$
Ou encore ne m’intéresser qu’aux lignes qui, en dehors des espaces, commencent par 5 caractères en majuscule suivi de =.
antoine@dressing:~/scripts$ cat gitpuller.sh | egrep "^\s*[A-Z]{5}="
REPOS=($(find $local_repository_folder -name ".git" -type d))
antoine@dressing:~/scripts$
Pour info, l’usage de cat
avant le pipe
est pratique visuellement mais on peut tout à fait donner le fichier directement à grep
ce qui donne le même résultat.
antoine@dressing:~/scripts$ egrep "^\s*[A-Z]{5}=" gitpuller.sh
REPOS=($(find $local_repository_folder -name ".git" -type d))
antoine@dressing:~/scripts$
On peut aussi faire cette recherche sur l’ensemble des fichiers du dossier.
antoine@dressing:~/scripts$ rgrep -E "^\s*[A-Z]{5}=" .
./abuseipchecker.sh: OWNER=$(whois $IP_TO_CHECK)
./gitpullerdemo.sh:REPOS=($(find $local_repository_folder -name ".git" -type d))
./gitpuller.sh:REPOS=($(find $local_repository_folder -name ".git" -type d))
antoine@dressing:~/scripts$
Les sommes de contrôle
Lorsque l’on échangeait des données à l’aide de connexion RTC ou que l’on stockait des données sur des supports magnétiques (disquettes, bandes) il était fréquent que les données soient corrompues.
Pour vérifier que les données n’ont pas été altérées entre l’émetteur et le récepteur, on peut utiliser les sommes de contrôles (checksum) : on applique un algorithme mathématique à un fichier pour produire un nombre. Un moyen simple de savoir de quels algorithme tu disposes, tu peux lister les fichiers terminant par sum
dans le dossier /usr/bin
.
antoine@dressing:~$ ls /usr/bin/*sum
/usr/bin/b2sum /usr/bin/cksum /usr/bin/md5sum /usr/bin/sha1sum /usr/bin/sha224sum /usr/bin/sha256sum /usr/bin/sha384sum /usr/bin/sha3sum /usr/bin/sha512sum /usr/bin/shasum /usr/bin/sum
antoine@dressing:~$
Les binaires /usr/bin/shannnsum
sont des alias de /usr/bin/shasum
.
Plusieurs problématiques se présentent lors du choix de l’algorithme : est-il fiable ou des pirates l’ont-ils percé ? Est-il disponible sur la machine du destinataire ? Est-il rapide ou très demandeur de ressources ?
md5
et sha1
sont considérés comme percés, il est déconseillé de les utiliser car un attaquant pourrait rendre la somme de contrôle identique tout en ayant altéré les données.
Idéalement, plus le nombre dans l’alias de shasum
est élevé mieux c’est. Cependant il n’est ni certain que la même valeur soit présente chez le récepteur et surtout plus ce sera élevé et plus cela pourrait prendre de temps à calculer.
antoine@dressing:~$ ALGO="sha3sum sha224sum sha256sum sha384sum sha512sum"
for OSEF in ${ALGO}; do echo $(time $OSEF CentOS-7-x86_64-NetInstall-2009.iso); done
real 0m1,321s
user 0m1,249s
sys 0m0,072s
088dcf34fd055b995e4ec613e26edcab757bcd7449d8427018b7c59e CentOS-7-x86_64-NetInstall-2009.iso
real 0m1,247s
user 0m1,202s
sys 0m0,044s
3da75adf68759dff05f5180397241f32f17f4178a03ea41012b0cd03 CentOS-7-x86_64-NetInstall-2009.iso
real 0m1,250s
user 0m1,202s
sys 0m0,048s
b79079ad71cc3c5ceb3561fff348a1b67ee37f71f4cddfec09480d4589c191d6 CentOS-7-x86_64-NetInstall-2009.iso
real 0m0,875s
user 0m0,826s
sys 0m0,048s
cbfbe92e824020beeba880aa9d3aac816ee9353f9996dd41c02d62ff3684c2f7f2f34e8097129560a7270f65cb350c33 CentOS-7-x86_64-NetInstall-2009.iso
real 0m0,872s
user 0m0,811s
sys 0m0,060s
bee6f754580b167e13975b919605d704be726b8da53d0976a5266d2d3eac5c07ddf3130a39a2d97548e8ba61e2e61636cfe11be03b8999fca0a47d4ddc6e8148 CentOS-7-x86_64-NetInstall-2009.iso
Bon l’exemple ci-dessous me semble donner un résultat totalement inversé. Il y a peut-être une explication mais là je sèche. Si t’as une idée, hésite pas à m’expliquer.
Toujours est-il, l’intérêt des sommes de contrôle est de les comparer avec celle publiée par l’émetteur du fichier. Par conséquent, il vaut mieux trouver cette valeur ailleurs qu’a l’endroit exact où tu télécharge un fichier : un attaquant qui aurait compromis un fichier pourrait avoir modifié la valeur de cette somme. J’ai regardé pour Debian et la somme est stockée au même endroit que l’ISO. Mais ils signent les fichiers de somme par clé GPG.
Bon j’ai téléchargé l’ISO DVD de Debian 12 debian-12.8.0-amd64-DVD-1.iso, le fichier de somme de contrôle SHA256SUMS et le fichier de signature de celui-ci SHA256SUMS.sign.
On va d’abord chercher à déterminer par quelle clé le fichier de somme de contrôle a été signé.
antoine@dressing:~$ gpg --verify SHA256SUMS.sign SHA256SUMS
gpg: Signature faite le sam. 09 nov. 2024 06:35:04 -10
gpg: avec la clef RSA DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Impossible de vérifier la signature : No public key
On télécharge la clé gpg
correspondante.
antoine@dressing:~$ gpg --keyserver keyring.debian.org --recv-keys 0xDF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: clef DA87E80D6294BE9B : clef publique « Debian CD signing key <debian-cd@lists.debian.org> » importée
gpg: Quantité totale traitée : 1
gpg: importées : 1
Ouf, on peut enfin vérifier que le fichier… de vérification est Ok.
antoine@dressing:~$ gpg --verify SHA256SUMS.sign SHA256SUMS
gpg: Signature faite le sam. 09 nov. 2024 06:35:04 -10
gpg: avec la clef RSA DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Bonne signature de « Debian CD signing key <debian-cd@lists.debian.org> » [inconnu]
gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance.
gpg: Rien n'indique que la signature appartient à son propriétaire.
Empreinte de clef principale : DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B
Bon techniquement, SHA256SUMS a bien été signé par une clé gpg
de Debian mais mon système ne sait pas s’il doit faire confiance à cette clé. On va le rassurer et lui indiquer le niveau de confiance que l’on applique à cette clé.
antoine@dressing:~$ gpg --edit-key DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pub rsa4096/DA87E80D6294BE9B
créé : 2011-01-05 expire : jamais utilisation : SC
confiance : inconnu validité : inconnu
sub rsa4096/642A5AC311CD9819
créé : 2011-01-05 expire : jamais utilisation : E
[ inconnue] (1). Debian CD signing key <debian-cd@lists.debian.org>
gpg> trust
pub rsa4096/DA87E80D6294BE9B
créé : 2011-01-05 expire : jamais utilisation : SC
confiance : inconnu validité : inconnu
sub rsa4096/642A5AC311CD9819
créé : 2011-01-05 expire : jamais utilisation : E
[ inconnue] (1). Debian CD signing key <debian-cd@lists.debian.org>
Décidez maintenant de la confiance que vous portez en cet utilisateur pour
vérifier les clefs des autres utilisateurs (en regardant les passeports, en
vérifiant les empreintes depuis diverses sources, etc.)
1 = je ne sais pas ou n'ai pas d'avis
2 = je ne fais PAS confiance
3 = je fais très légèrement confiance
4 = je fais entièrement confiance
5 = j'attribue une confiance ultime
m = retour au menu principal
Quelle est votre décision ? 4
pub rsa4096/DA87E80D6294BE9B
créé : 2011-01-05 expire : jamais utilisation : SC
confiance : totale validité : inconnu
sub rsa4096/642A5AC311CD9819
créé : 2011-01-05 expire : jamais utilisation : E
[ inconnue] (1). Debian CD signing key <debian-cd@lists.debian.org>
Veuillez remarquer que la validité affichée pour la clef n'est pas
forcément correcte avant d'avoir relancé le programme.
Bon je l’ai lancé deux fois, la seconde fois je n’ai pas reçu l’avertissement. Mais lorsque je vérifie la signature de SHA256SUMS, gpg
n’est quand même pas totalement jouasse.
antoine@dressing:~$ gpg --verify SHA256SUMS.sign SHA256SUMS
gpg: Signature faite le sam. 09 nov. 2024 06:35:04 -10
gpg: avec la clef RSA DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Bonne signature de « Debian CD signing key <debian-cd@lists.debian.org> » [inconnu]
gpg: Attention : cette clef n'est pas certifiée avec une signature de confiance.
gpg: Rien n'indique que la signature appartient à son propriétaire.
Empreinte de clef principale : DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B
Malgré ce résultat en demie teinte, je vais quand même vérifier que mon ISO n’est pas altéré (l’empreinte de la clé correspond à celle publiée sur le site de Debian).
antoine@dressing:~$ sha256sum --check SHA256SUMS
debian-12.8.0-amd64-DVD-1.iso: Réussi
sha256sum: debian-12.8.0-amd64-DVD-10.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-10.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-11.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-11.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-12.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-12.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-13.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-13.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-14.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-14.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-15.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-15.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-16.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-16.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-17.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-17.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-18.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-18.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-19.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-19.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-2.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-2.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-20.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-20.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-21.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-21.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-3.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-3.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-4.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-4.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-5.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-5.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-6.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-6.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-7.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-7.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-8.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-8.iso: Échec d'ouverture ou de lecture
sha256sum: debian-12.8.0-amd64-DVD-9.iso: Aucun fichier ou dossier de ce type
debian-12.8.0-amd64-DVD-9.iso: Échec d'ouverture ou de lecture
sha256sum: Attention : 20 fichiers de la liste n'ont pas pu être lus
J’aurai dû m’y attendre : j’ai pas téléchargé non plus tous les fichiers, juste le DVD 1. On va alors ignorer les fichiers absents.
antoine@dressing:~$ sha256sum --check SHA256SUMS --ignore-missing
debian-12.8.0-amd64-DVD-1.iso: Réussi
Bon te parler de nano
et de vim
ça m’a pas passionné plus que ça mais il y a quelques points dont j’ai tiré bénéfice très rapidement :
- Virer les erreurs de
du
vers/dev/null
c’est vachement chouette (ça évite le--exclude=
), - Utiliser une
regexp
(genre la plus basique) pour extraire les lignes d’un log Apache qui commencent par les deux premiers octets d’un réseau /16. - Vérifier que les checksums d’un fichier soient identiques après l’avoir déplacé vers un autre serveur et être certain que je puisse le supprimer du premier.
Je garde quand même une saveur aigre-douce pour les temps de calculs qui semblent inversés par rapport à ce à quoi je m’attendais.
Dans tous les cas, le fait de (re)voir les bases reste un travail très intéressant.
Ah oui, si tu as raté le commentaire de Tzkuat en fin d’article précédent : les supports de cours LPIC-1 sont disponibles gratuitement en français et il y a même une version pdf.
