Linux ligne de commande

Pour chaque chose répétitive et programmable, il y a probablement une commande pertinente.

Pour ceux qui sont habitués à l’interface graphique, utiliser la ligne de commande peut constituer un problème : celui d’interagir avec l’ordinateur en utilisant de simples commandes textuelles.

Les commandes présentées ici sont spécifiques à Linux et se comportent en général de manière similaire, quelle que soit la distribution.

Les commandes Linux ont souvent ajouté des fonctionnalités par rapport aux spécifications POSIX.

4 commentaires Donner une note  l'article (5)

Article lu   fois.

Les deux auteur et traducteur

Traducteur : Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Introduction à Linux

1-1. Qu'est-ce que Linux ?

Citation de Wikipédia

Linux est, au sens restreint, le noyau de système d'exploitation Linux, et au sens large, tout système d'exploitation fondé sur le noyau Linux. Cet article couvre le sens large.

À l'origine, le noyau Linux a été développé pour les ordinateurs personnels compatibles PC, et devait être accompagné des logiciels GNU pour constituer un système d'exploitation. Les partisans du projet GNU promeuvent depuis le nom combiné GNU/Linux. Depuis les années 2000, le noyau Linux est utilisé sur du matériel informatique allant des téléphones portables aux superordinateurs, et n'est pas toujours accompagné de logiciels GNU. C'est notamment le cas d'Android, qui équipe plus de 80 % des smartphones.

Le noyau Linux a été créé en 1991 par Linus Torvalds. C'est un logiciel libre. Les distributions Linux ont été, et restent, un important vecteur de popularisation du mouvement open source.

1-2. Pourquoi utiliser Linux?

  • Plus rapide, plus sécurisé, plus stable ;

    • cela aide les développeurs du monde entier à contribuer plutôt qu'une seule entreprise ;
  • hautement configurable ;
  • adapté à un environnement mono ou multi-utilisateur ;
  • hiérarchie et autorisations bien définies pour permettre la mise en réseau de différents groupes et sites ;
  • ensemble solide de commandes pour automatiser les tâches répétitives ;
  • lisez plus d'informations sur l'utilisation de Linux s'il convient à vos besoins informatiques sur computefreely

1-3. Où Linux est-il déployé ?

  • Sur les serveurs ;
  • sur les supercalculateurs ;

    • Pour citer l'article Wikipédia, "Depuis novembre 2017, tous les supercalculateurs référencés (100 % des TOP 500) utilisent un système d'exploitation basé sur le noyau Linuxl" ;
  • l'informatique embarquée comme les POS, Raspberry Pi ;
  • les smartphones :

    • Android – construit sur le noyau Linux,
    • iOS – basé sur Unix ;
  • les ordinateurs à domicile et en entreprise ;
  • l'informatique embarquée (Raspberry, Arduino, etc.) ;
  • beaucoup d'autres utilisations, merci d'être open source.
  • Usage Share of Operating Systems

1-4. Les distributions Linux

Il y a des versions variées de Linux appelées distributions (ou distros), pour répondre aux besoins des utilisateurs débutants ou avancés ainsi que des distributions hautement personnalisées pour des usages précis.

Installation

D’habitude, vous trouverez des instructions d'installation sur le site respectif des distributions que vous choisissez. Si vous avez besoin d'une vue générale du processus d'installation, ceci devrait vous aider :

1-5. Liste de ressources

2. Introduction à la ligne de commande

Pour chaque chose répétitive et programmable, il y a probablement une commande pertinente. Demandez à vos pairs ou cherchez en ligne avant de commencer à écrire un script. Rappelez-vous qu’Unix est sorti à la fin des années 60. Il doit certainement avoir une commande pour votre besoin.

Pour ceux qui sont habitués à l’interface graphique, utiliser la ligne de commande peut constituer un problème : celui d’interagir avec l’ordinateur en utilisant de simples commandes textuelles. Après utilisation d’une semaine ou deux, les choses deviendront très systématiques et l’interface graphique fera ressentir une inadaptation aux tâches fréquentes. Avec une utilisation continue, rappeler des commandes variées deviendra plus facile. Les raccourcis, l’historique, les alias et la complétion par tabulation aideront à ce processus.

Si vous avez utilisé un calculateur scientifique, vous devriez savoir qu’il est manipulable avec beaucoup trop de fonctionnalités à l’étroit dans un petit écran et pléthore de boutons à multi-usage. Les commandes et les raccourcis sont bien plus percutants que ceux d'un terminal.

  • Les commandes présentées ici sont spécifiques à Linux et se comportent en général de manière similaire, quelle que soit la distribution.
  • Les commandes Linux ont souvent ajouté des fonctionnalités par rapport aux spécifications POSIX.
  • Si une commande n’est pas trouvée dans une distribution, il faut soit l’installer manuellement, ou il existe probablement une solution.
  • Le shell bash version 4+ est utilisé tout au long de ce tutoriel

2-1. système de fichiers

Avant de plonger dans l’océan des commandes, passons en revue rapidement le système de fichiers Linux. Si vous avez utilisé Windows, vous devriez être familier avec C:, D:, etc.

Sous Linux, la structure des dossiers commence avec le symbole / qui fait référence au dossier racine (root).

man hier donne la description de la hiérarchie du système de fichiers. Quelques exemples :

  • / : c’est le dossier racine. C’est le départ de toute arborescence ;
  • /bin : ce dossier contient les programmes exécutables nécessaires au mode single user et pour rendre le système opérationnel et le réparer ;
  • /home : sur les machines avec un dossier home pour les utilisateurs, ceux-ci sont en général dans ce dossier. La structure de ce dossier dépend des décisions locales d’administration ;
  • /tmp : ce dossier contient les fichiers temporaires qui peuvent être supprimés sans notification, comme par un job régulier ou un démarrage système ;
  • /usr : ce dossier est souvent monté dans une partition séparée. Elle doit contenir seulement des données en lecture seule, partageable, pouvant être montée par des machines variées lançant Linux !
  • /usr/bin : c’est le dossier primaire pour les programmes exécutables. La plupart des programmes exécutés par des utilisateurs normaux et qui ne sont pas requis au démarrage ou pour réparer le système, et qui ne sont pas installés localement devraient être placés dans ce dossier ;
  • /usr/share : ce dossier contient des sous-dossiers avec des données spécifiques aux applications, pouvant être partagées à travers différentes architectures du même OS. Souvent, une chose présente dans ce dossier sera /usr/doc, /usr/lib ou /usr/man.

2-1-1. Chemins relatifs ou absolus

Un chemin absolu ou chemin complet pointe vers la même position, quel que soit le dossier courant. Pour cela, il doit contenir le dossier racine.

Par opposition, un chemin relatif démarre du dossier en cours, évitant de devoir fournir le chemin complet. Un nom de fichier peut être considéré comme un chemin relatif basé sur le dossier en cours. Si le dossier courant n’est pas le dossier parent du fichier, un message d’erreur « fichier non trouvé » sera retourné si le fichier est adressé par son nom.

  • /home/learnbyexample : chemin absolu.
  • ../design : chemin relatif.

Lectures supplémentaires

2-2. Interface en ligne de commande

L’interface en ligne de commande (CLI en anglais pour Command Line Interface) nous permet d’interagir avec l’ordinateur en utilisant des commandes textuelles.

Par exemple : la commande cd devrait vous aider à naviguer dans un dossier particulier, et la commande ls, à afficher le contenu du dossier. En interface graphique, vous utilisez un explorateur pour la navigation, fonctionnant par « point and click ». Le contenu du dossier est affiché par défaut.

Les termes de shell et de terminal sont souvent utilisés pour dire la même chose : un prompt où l’utilisateur tape et exécute des commandes. Cependant, les deux termes sont différents.

  • Le Shell est interpréteur de ligne de commande, il met en place les règles de syntaxe pour invoquer les commandes, etc.
  • Le Terminal est l’environnement d’entrée/sortie du texte, responsable des détails visuels comme la taille de police, la couleur, etc.

Nous apprendrons plus sur le Shell dans les chapitres suivants. Pour le moment, ouvrez un terminal et essayez ces commandes en les tapant et en appuyant sur la touche entrée. Vous pouvez repérer la ligne de commande par le prompt $ en début de ligne.

 
Sélectionnez
$ cat /,etc./shells
# /,etc./shells: login shells valides
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/bin/tcsh
/usr/bin/tcsh
$ echo "$SHELL"
/bin/bash

Votre prompt de commande peut être différent, pour le moment vous pouvez laisser celui-ci inchangé ou le changer avec le simple prompt que je préfère en exécutant PS1="$ ".

Dans l’exemple ci -dessus, la commande cat est utilisée pour afficher le contenu d’un fichier et la commande echo pour afficher le contenu d’une variable. Ces commandes ont d’autres usages, qui seront couverts plus tard.

2-3. Aide des commandes

La plupart des distributions à usage personnel fournissent une documentation pour les commandes déjà installées. Avoir accès à la documentation depuis le terminal est pratique. Il y a plusieurs façons de faire pour obtenir des informations spécifiques :

  • la commande man est une interface pour faire référence aux manuels

    • souvent utilisée avec la commande less , presser la touche q pour quitter la page de man et h pour obtenir de l’aide,
    • pour les commandes , la commande info donne la documentation complète,
    • vous pouvez aussi les lire en ligne , par exemple GNU Coreutils manual contient les manuels de la plupart des commandes couvertes par ce tutoriel ;
  • man man donnera les détails de la commande man elle-même ;
  • man bash va vous donner la page de manuel de bash

    • man find | gvim – pour ouvrir la page de manuel dans votre éditeur de texte favori ;
  • man -k printf va chercher la description courte dans toutes les pages de manuel pour la chaîne printf

    • man -k est équivalent à la commande apropos ;
  • excellente ressource unix.stackexchange: How do I use man pages to learn how to use commands?
  • voir aussi wiki.archlinux: man page.

Pour certaines opérations, le shell fournit son propre ensemble de commandes, appelées commandes internes :

 
Sélectionnez
$ type cd
cd est une primitive du shell
$ type sed
sed est /bin/sed
$ plusieurs commandes peuvent être données en arguments
$ type pwd awk
pwd est une primitive du shell
awk est /usr/bin/awk
$ type ls
ls est un alias vers `ls --color=auto'
$ type -a ls
ls est un alia vers `ls --color=auto'
ls est /bin/ls

la commande help fournit la documentation pour les commandes internes

  • help help page help sur la commande help ;
  • l'option -m va afficher l’usage dans un pseudoformat manpage ;
  • l’option -d donne une courte description pour chaque sujet, similaire à la commande whatis ;
  • la commande help par elle-même sans argument va afficher toutes les commandes shell définies en interne.
 
Sélectionnez
$ help pwd
pwd: pwd [-LP]
    Affiche le nom du répertoire de travail courant. 
    
    Options : 
      -L    affiche la valeur de $PWD s'il nomme le répertoire de travail courant 
         
      -P    affiche le répertoire physique, sans aucun lien symbolique 
    
    Par défaut, « pwd » se comporte comme si « -L » était spécifié. 
    
    Code de retour :
    Renvoie 0 à moins qu'une option non valable ne soit donnée ou que le répertoire courant ne peut pas être lu.
$ help -d compgen
compgen – Affiche les complétions possibles selon les options.

Voici quelques commandes d’accompagnement :

  • whatis affiche une description sur une ligne ;
  • whereis localise le binaire, la source, et les fichiers de man pour une commande ;
  • explainshell est une application web qui affiche le texte d’aide concordant avec chaque argument d’une ligne de commande, exemple: tar xzvf archive.tar.gz ;
  • ch est un script, inspiré par explainshell, pour extraire la description des options depuis les pages d’aide man.
 
Sélectionnez
$ whatis grep 
grep (1)             - Afficher les lignes correspondant à un motif donné 

$ whereis awk 
awk: /usr/bin/awk /usr/bin/X11/awk /usr/share/man/man1/awk.1.gz
$ ch sort -k
       sort – trie les lignes d'un fichier texte
       -k, --key=KEYDEF
              trie via une clé; KEYDEF donne l'emplacement et le type

2-4. Faire une chose et la faire bien

La philosophie d'Unix s’applique aussi à Linux :

  • écrire des programmes qui font une seule chose, mais la font bien ;
  • écrire des programmes pouvant travailler ensemble ;
  • écrire des programmes pour gérer des flux de texte, car c’est une interface universelle.

Les exemples donnés ci-dessous sont uniquement pour la démonstration, il y aura plus de détails ultérieurement.

2-4-1. Structure de commande

Commandes sans option :

  • clear efface l’ écran du terminal ;
  • top affiche les processus Linux.

Commandes avec options :

  • ls -l affiche le contenu d’un dossier, utilisation en format long listing ;
  • df -h retourne l’utilisation de l’espace disque du système de fichiers, affiche les tailles en format lisible par un humain (ex. : 1K 234M 2G).

Commandes avec arguments :

  • mkdir projet crée un dossier nommé « projet » dans le dossier courant ;
  • man sort page de manuel de la commande sort ;
  • wget https://s.ntnu.no/bashguide.pdf télécharge le fichier sur Internet.

commandes avec options et arguments :

  • rm -r projet supprime le dossier « projet » ;
  • paste -sd, ip.txt combine toutes les lignes du fichier « ip.txt » sur une seule ligne en utilisant , comme délimiteur.

single quotes vs double quotes

  • les single quotes préservent la valeur littérale de chaque caractère entre ceux-ci ;
  • les double quotes préservent la valeur littérale de tous les caractères entre ceux-ci à l’exception des caractères '$', '`', '\', et '!' , quand l’extension de l’historique est activée.
  • Voir aussi stackoverflow: Difference between single and double quotes
 
Sélectionnez
$ echo '$SHELL'
$SHELL
$ echo "$SHELL"
/bin/bash

2-4-2. Réseau de commandes

Redirection de sortie d’une commande :

  • vers une autre commande :

    • du -sh * | sort -h calcule la taille des fichiers/dossiers, affiche la taille de façon lisible par un humain, sortie qui est ensuite triée ;
  • vers un fichier (au lieu d’afficher sur un terminal) :

    • grep 'pass' *.log > pass_list.txt écrit vers le fichier (si le fichier existe déjà, il est écrasé),
    • grep 'error' *.log >> errors.txt ajoute au fichier (crée celui-ci si nécessaire) ;
  • vers une variable :

    • p=$(pwd) sauve la sortie de la commande pwd vers la variable p, il ne doit pas avoir d’espaces autour de = .

Redirection d’entrée :

  • wc -l < file.txt utilisé pour juste récupérer le nombre de lignes, sans afficher le nom de fichier ;
  • tr 'a-z' 'A-Z' < ip.txt certaines commandes comme tr fonctionnent seulement sur stdin.

Redirection d’erreur :

  • xyz 2> cmderror.log en supposant la non-existence de la commande xyz, cela devrait donner une erreur et rediriger vers le fichier spécifié.

Redirection de sortie de commande en tant que fichier d’entrée :

  • comm -23 <(sort file1.txt) <(sort file2.txt) procède à la substitution, évitant de devoir créer un fichier temporaire.

Combiner la sortie de plusieurs commandes :

  • {head -n5 ~/.vimrc ; tail -n5 ~/.vimrc; } > vimrc_snippet.txt plusieurs commandes (séparées par ;) peuvent être regroupées dans une liste.

Substitution de commandes :

  • sed -i "s|^|$(basename $PWD)/|" dir_list.txt ajoute le chemin du dossier courant et un caractère slash au début de chaque ligne.

Notez l'usage des double quotes.

stdin, stdout et stderr

  • < ou 0< est le gestionnaire de stdin (entrée) ;
  • > or 1> est le gestionnaire de stdout (sortie) ;
  • 2> est le gestionnaire de stderr (sortie des erreurs).
  • Voir aussi stackoverflow: stdin, stdout and stderr

Plus de détails dans le chapitre sur le shellShell.

3. Fichiers et dossiers

Jetons un œil aux commandes communes à la navigation dans les répertoires, la création/modification de fichiers et de dossiers. Pour certaines commandes, une liste des options les plus communes est communiquée.

Prenez l’habitude d’utiliser la commande man pour vous renseigner sur une commande. Par exemple : man ls.

Les descriptions courtes pour les commandes sont montrées en tant que texte cité (pris depuis whatis ou help -d).

3-1. pwd

Affiche le nom du dossier courant.

  • En plus de servir à connaître le dossier courant, souvent utilisé pour copier le chemin absolu et être collé ailleurs, comme dans un script.
  • Certains émulateurs de terminal affichent le chemin du dossier en cours dans le titre de fenêtre.
 
Sélectionnez
$ pwd
/home/learnbyexample

3-2. cd

Change le dossier en cours du shell.

  • Comme pwd, la commande cd est interne au shell.
  • Voyons un exemple de changement de dossier courant vers un autre dossier et retour en arrière.
  • Spécifier / en fin de chemin est optionnel.
 
Sélectionnez
$ pwd
/home/learnbyexample
$ # fourniture d'un chemin d'accès absolu en argument
$ cd /,etc.
$ pwd
/,etc.
$ # pour retourner au précédent dossier de travail
$ # s'il y a un dossier nommé '-', utilisez './-' pour retourner à ce dossier
$ cd -
/home/learnbyexample
$ pwd
/home/learnbyexample
  • Les chemins relatifs le sont par rapport au dossier courant.
  • . se réfère au dossier courant.
  • .. se réfère au dossier une hiérarchie au-dessus.
  • ../.. se réfère à deux hiérarchies au-dessus et ainsi de suite.
 
Sélectionnez
$ pwd
/home/learnbyexample

$ # va dans le dossier une hiérarchie au-dessus
$ cd ..
$ pwd
/home
$ # va dans le dossier 'learnbyexample', présent dans le dossier courant
$ # './' est optionnel dans ce cas
$ cd ./learnbyexample
$ pwd
/home/learnbyexample
$ # va dans le dossier deux hiérarchies au-dessus
$ cd ../..
$ pwd
/
  • cd ~/ ou cd ~ ou cd vont aller dans le dossier spécifié par la variable shell HOME (qui est actuellement positionnée sur le dossier home de l'utilisateur)
 
Sélectionnez
$ pwd
/
$ echo "$HOME"
/home/learnbyexample
$ cd
$ pwd
/home/learnbyexample

Lectures complémentaires :

3-3. clear

Efface l’écran du terminal.

Vous pouvez aussi utiliser le raccourci Ctrl+ l pour effacer le terminal (en plus, ceci conserve le texte tapé).

3-4. ls

Liste le contenu d’un dossier.

  • Par défaut, la sortie de ls est triée par ordre alphabétique.
 
Sélectionnez
$ # sans argument, le contenu du dossier courant est affiché
$ ls
backups  hello_world.py  palindrome.py  projects    todo
ch.sh    ip.txt          power.log      report.log  workshop_brochures

$ # les chemins relatifs/absolus peuvent être donnés en arguments
$ ls /var/
backups  crash  local  log   metrics  run   spool
cache    lib    lock   mail  opt      snap  tmp

$ # pour plusieurs arguments, le listing est organisé par dossier 
$ ls workshop_brochures/ backups/
backups:
chrome_bookmarks_02_07_2018.html  dot_files
workshop_brochures:
Python_workshop_2017.pdf  Scripting_course_2016.pdf
$ # listein en colomne sinple
$ ls -1 backups/
chrome_bookmarks_02_07_2018.html
dot_files
  • -F ajoute un caractère à chaque fichier indiquant son type (autre que fichier régulier) :

    • / pour les dossiers ;
    • * pour les fichiers exécutables ;
    • @ pour les liens symboliques ;
    • | pour les pipes ;
    • = pour les sockets ;
    • le détail des indicateurs est décrit dans info ls, pas dans man ls.
 
Sélectionnez
$ ls -F
backups/  hello_world.py*  palindrome.py*  projects@   todo
ch.sh*    ip.txt           power.log       report.log  workshop_brochures/
$ # si vous voulez juste distinguer les fichiers des dossiers, utilisez -p
$ ls -p
backups/  hello_world.py  palindrome.py  projects    todo
ch.sh     ip.txt          power.log      report.log  workshop_brochures/
  • ou utilisez l’option color :

Image non disponible

  • format long listing
  • montre les détails comme les permissions, le possesseur, la taille, le timestamp, etc.

    • Voir la section chmod pour les détails sur les permissions, les groupes, etc. ;
  • les types de fichiers sont distingués de la façon suivante : d pour les dossiers, - pour les fichiers réguliers, l pour les liens symboliques, etc.
 
Sélectionnez
$ ls -l
total 84
drwxrwxr-x 3 learnbyexample eg  4096 Jul  4 18:23 backups
-rwxr-xr-x 1 learnbyexample eg  2746 Mar 30 11:38 ch.sh
-rwxrwxr-x 1 learnbyexample eg    41 Aug 21  2017 hello_world.py
-rw-rw-r-- 1 learnbyexample eg    34 Jul  4 09:01 ip.txt
-rwxrwxr-x 1 learnbyexample eg  1236 Aug 21  2017 palindrome.py
-rw-r--r-- 1 learnbyexample eg 10449 Mar  8  2017 power.log
lrwxrwxrwx 1 learnbyexample eg    12 Jun 21 12:08 projects -> ../projects/
-rw-rw-r-- 1 learnbyexample eg 39120 Feb 25  2017 report.log
-rw-rw-r-- 1 learnbyexample eg  5987 Apr 11 11:06 todo
drwxrwxr-x 2 learnbyexample eg  4096 Jul  5 12:05 workshop_brochures
$ # pour voir la taille en format humainement lisible, plutôt qu'en nombre d'octets
$ ls -lh power.log
-rw-r--r-- 1 learnbyexample eg 11K Mar  8  2017 power.log
$ # utilisez l'option -s à la place de -l si seule l'information de taille est requise
$ ls -1sh power.log report.log
12K power.log
40K report.log
  • changement des critères de sortie ;
  • utilisez -t pour trier par date, souvent combiné à -r pour inverser l’ordre pour afficher les fichiers les plus récents en dernier ;
  • l’option -S trie par taille de fichiers (ne convient pas aux dossiers) ;
  • l’option -v fait un tri de version (convient aux fichiers avec des nombres dans leur nom) ;
  • l’option -X permet de trier par extension de fichier (c'est-à-dire : les caractères après le dernier . dans le nom de fichier)
 
Sélectionnez
$ ls -lhtr
total 84K
-rw-rw-r-- 1 learnbyexample eg  39K Feb 25  2017 report.log
-rw-r--r-- 1 learnbyexample eg  11K Mar  8  2017 power.log
-rwxrwxr-x 1 learnbyexample eg 1.3K Aug 21  2017 palindrome.py
-rwxrwxr-x 1 learnbyexample eg   41 Aug 21  2017 hello_world.py
-rwxr-xr-x 1 learnbyexample eg 2.7K Mar 30 11:38 ch.sh
-rw-rw-r-- 1 learnbyexample eg 5.9K Apr 11 11:06 todo
lrwxrwxrwx 1 learnbyexample eg   12 Jun 21 12:08 projects -> ../projects/
-rw-rw-r-- 1 learnbyexample eg   34 Jul  4 09:01 ip.txt
drwxrwxr-x 3 learnbyexample eg 4.0K Jul  4 18:23 backups
drwxrwxr-x 2 learnbyexample eg 4.0K Jul  5 12:05 workshop_brochures
$ ls -X
backups   todo                power.log   hello_world.py  ch.sh
projects  workshop_brochures  report.log  palindrome.py   ip.txt
  • les fichiers commençant par un point sont considérés comme des fichiers cachés.
 
Sélectionnez
$ # l'option -a montre également les fichiers cachés
$ ls -a backups/dot_files/
.  ..  .bashrc  .inputrc  .vimrc

$ # . et .. are sont des dossiers spéciaux pointant sur le dossier courant et le dossier parent

$ # si vous vous rappelez, nous les avons utilisés pour spécifier des chemins relatifs
$ # doc, 'ls', 'ls .' et 'ls backups/..' vont donner le même résultat
$ ls -aF backups/dot_files/
./  ../  .bashrc  .inputrc  .vimrc
$ # utilisez l'option -A pour montrer les fichiers cachés incluant les dossiers spéciaux . et ..
$ ls -A backups/dot_files/
.bashrc  .inputrc  .vimrc
  • Utilisez l'option -R pour lister également les dossiers de façon récursive.
 
Sélectionnez
$ ls -ARF
.:
backups/  hello_world.py*  palindrome.py*  projects@   todo
ch.sh*    ip.txt           power.log       report.log  workshop_brochures/

./backups:
chrome_bookmarks_02_07_2018.html  dot_files/
./backups/dot_files:
.bashrc  .inputrc  .vimrc
./workshop_brochures:
Python_workshop_2017.pdf  Scripting_course_2016.pdf
  • la commande tree affiche le contenu d’un dossier de façon récursive comme une structure en arbre ;
  • vous aurez à installer cette commande ou avoir une commande équivalente comme gvfs-tree.
 
Sélectionnez
$ # l'option -h va afficher les fichiers cachés
$ gvfs-tree -h
file:///home/learnbyexample/ls_ex
|-- backups
|   |-- chrome_bookmarks_02_07_2018.html
|   `-- dot_files
|       |-- .bashrc
|       |-- .inputrc
|       `-- .vimrc
|-- ch.sh
|-- hello_world.py
|-- ip.txt
|-- palindrome.py
|-- power.log
|-- projects -> ../projects/
|-- report.log
|-- todo
`-- workshop_brochures
    |-- Python_workshop_2017.pdf
    `-- Scripting_course_2016.pdf
  • souvent, nous voulons filtrer les dossiers/fichiers à afficher ;
  • les commandes comme find fournissent des fonctionnalités étendues à cette fin ;
  • le shell lui-même fournit une technique correspondante appelée jokers/glob

    • Voir la section jokers Shell pour plus d’exemples et détails ;
  • les débutants associent à tort la technique du glob à la commande ls, mais la technique du glob est montrée ci-dessous en démonstration, utilisant la commande echo :
 
Sélectionnez
$ # tous les arguments non entre guillemets sont soumis à interprétation par le système glob du shell.
$ echo *.py *.log
hello_world.py palindrome.py power.log report.log
$ echo '*.py' *.log
*.py power.log report.log

$ # liste seulement les fichiers se terminant par .py en affichage long
$ ls -l *.py
-rwxrwxr-x 1 learnbyexample eg   41 Aug 21  2017 hello_world.py
-rwxrwxr-x 1 learnbyexample eg 1236 Aug 21  2017 palindrome.py
$ # correspond aux noms de fichiers commençant avec les caractères alphabétiques c/C/d/D/e/E/f/F/g/G/h/H/i
$ echo [c-i]*
ch.sh hello_world.py ip.txt
$ ls -sh [c-i]*
4.0K ch.sh  4.0K hello_world.py  4.0K ip.txt
  • utilisez l’option -d pour ne pas montrer le contenu des dossiers :
 
Sélectionnez
$ echo b*
backups
$ # comme backups est un dossier, ls va lister son contenu
$ ls b*
chrome_bookmarks_02_07_2018.html  dot_files
$ # l'option -d va montrer l'entrée dossier plutôt que son contenu
$ ls -d b*
backups
$ # un moyen simple d'obtenir seulement les entrées dossier
$ # en supposant de simples noms de fichier sans espace, retour chariot, etc.
$ echo */
backups/ projects/ workshop_brochures/
$ ls -d */
backups/  projects/  workshop_brochures/

Lectures supplémentaires

3-5. mkdir

Crée un dossier.

  • Les noms de fichiers Linux peuvent utiliser n’importe quel caractère à l’exception de « / » et du caractère ASCII NULL.
  • Mettez les arguments entre guillemets si les noms contiennent des caractères comme des espaces, *, etc. pour prévenir toute interprétation du shell.

    • Le shell considère les espaces comme un séparateur d’arguments, * est un caractère pour la fonction glob, etc.
  • Sauf si nécessaire, essayez d’utiliser uniquement des caractères alphabétiques, et nombres, et des underscores pour les noms de fichier.
 
Sélectionnez
$ # un ou plusieurs chemins relatifs/absolus peuvent être donnés pour créer plusieurs dossiers
$ mkdir reports 'low power adders'
$ # les listes peuvent porter à confusion quand des noms de fichier contiennent des caractères comme un espace.
$ ls
low power adders  reports
$ ls -1
low power adders
reports
  • Utilisez l’option -p pour créer plusieurs hiérarchies de dossiers en une fois.
  • C’est aussi pratique si on a besoin de créer des dossiers dans des scripts sans avoir à vérifier s'ils existent déjà.
  • La variable spéciale $? donne le statut de sortie de la dernière commande exécutée.

    • 0 indique un succès, et une autre valeur indique un échec.
    • Voir la documentation des commandes respectives pour plus de détails
 
Sélectionnez
$ mkdir reports
mkdir: cannot create directory ‘reports’: File exists
$ echo $?
1
$ # quand -p est utilisé, mkdir ne donnera pas d'erreur si le dossier existe
$ mkdir -p reports
$ echo $?
0

$ # erreur, car 'a/b' n'existe pas
$ mkdir a/b/c
mkdir: cannot create directory ‘a/b/c’: No such file or directory
$ # avec -p, tout dossier non existant sera créé
$ mkdir -p a/b/c
$ ls -1R a
a:
b
a/b:
c
a/b/c:

Lectures supplémentaires

3-6. touch

  • Habituellement, les fichiers sont créés en utilisant un éditeur de texte ou en redirigeant la sortie d’une commande vers un fichier.
  • Mais quelquefois, par exemple pour tester le renommage d’un fichier, créer des fichiers vides est pratique.
  • La commande touch est principalement utilisée pour changer la date d’accès à un fichier (voir la section touchtouch du prochain chapitre).
  • Si un nom de fichier donné à touch n’existe pas, un fichier vide sera créé avec la date actuelle.
 
Sélectionnez
$ touch ip.txt
$ ls -1F
a/
ip.txt
low power adders/
reports/

3-7. rm

Supprime des fichiers ou des dossiers.

  • Pour supprimer des fichiers, spécifiez-les en tant qu’arguments séparés.
  • Pour supprimer des dossiers, utilisez l’option -r option (suppression récursive),
    utilisez l’option -f option pour forcer la suppression sans message pour les fichiers non existants et protégés en écriture (à condition que l’utilisateur ait les droits adéquats)
 
Sélectionnez
$ ls
a  ip.txt  low power adders  reports

$ rm ip.txt
$ ls
a  low power adders  reports
$ rm reports
rm: cannot remove 'reports': Is a directory
$ rm -r reports
$ ls
a  low power adders
$ # pour supprimer seulement un dossier quand il est vide,comme la commande 'rmdir'
$ rm -d a
rm: cannot remove 'a': Directory not empty
  • des fautes de frappe comme des espaces mal placés, de mauvaises entrées glob, etc. pourraient effacer des fichiers à tort.
  • En plus des sauvegardes et snapshots, il est possible de prendre des mesures d’atténuation :

    • en utilisant l’option -i pour supprimer interactivement chaque fichier ;
    • en utilisant echo comme un essai pour voir comment le glob se développer ;
    • en utilisant une commande de corbeille (voir les liens ci-dessous) à la place d’ rm
 
Sélectionnez
$ rm -ri 'low power adders'
rm: remove directory 'low power adders'? n
$ ls
a  low power adders
$ rm -ri a
rm: descend into directory 'a'? y
rm: descend into directory 'a/b'? y
rm: remove directory 'a/b/c'? y
rm: remove directory 'a/b'? y
rm: remove directory 'a'? y
$ ls
low power adders

Lecture supplémentaire

3-8. cp

Copie des fichiers et des dossiers.

  • Pour copier un seul fichier ou dossier, spécifiez la source comme premier argument et la destination comme second.
  • Comme pour la commande rm, utilisez -r pour les dossiers.
 
Sélectionnez
$ # Quand la destination est un dossier, les sources spécifiées sont placées dans celui-ci.
$ # rappel : . est un chemin relatif au dossier en cours
$ cp /usr/share/dict/words .
$ ls
low power adders  words
$ cp /usr/share/dict .
cp: omitting directory '/usr/share/dict'
$ cp -r /usr/share/dict .
$ ls -1F
dict/
low power adders/
words
  • Souvent, nous voulons faire une copie avant modification.
  • Dans ce cas, un nom différent peut être donné lors de la spécification de destination.
  • Si le fichier de destination existe, il sera écrasé (voir les options -i et -n pour éviter cela).
 
Sélectionnez
$ cp /usr/share/dict/words words_ref.txt
$ cp -r /usr/share/dict word_lists
$ ls -1F
dict/
low power adders/
word_lists/
words
words_ref.txt
  • De multiples fichiers et dossiers peuvent être copiés en une fois si la destination est un dossier.
  • En utilisant l’option -t, il est possible de spécifier la destination en premier, suivi par les sources (c’est pratique avec la commande find)
 
Sélectionnez
$ mkdir bkp_dot_files
$ # ici, ~ va être replacé par le nom du dossier home de l'utilisateur.
$ cp ~/.bashrc ~/.bash_profile bkp_dot_files/
$ ls -A bkp_dot_files
.bash_profile  .bashrc
  • Voir man cp et info cp pour plus d’options et la documentation complète.
  • Quelques options notables :

    • -u copie les fichiers sources seulement s'ils sont plus récents que ceux de la destination ou s’ils n’existent pas dans celle-ci ;
    • -b et --backup pour option de sauvegarde si un fichier de même nom existe dans la destination ;
    • l’option --preserve pour copier les fichiers en conservant les attributs tels que la date.

Lecture supplémentaire

3-9. mv

Déplace (renomme) des fichiers

  • Comme le nom le suggère, mv (pour move en anglais) peut déplacer des fichiers d’un emplacement à un autre.
  • Si plusieurs fichiers ont besoin d’être déplacés, l’argument de destination devra être un dossier (ou spécifié en utilisant l’option -t).
  • Contrairement à rm et cp, les arguments fichiers et dossiers ont la même syntaxe, aucune option additionnelle nécessaire.
  • Utilisez l’option -i pour être interrogé sur l’écrasement d’un même fichier dans la destination.
 
Sélectionnez
$ ls
bkp_dot_files  dict  low power adders  word_lists  words  words_ref.txt
$ mkdir backups
$ mv bkp_dot_files/ backups/
$ ls -F
backups/  dict/  low power adders/  word_lists/  words  words_ref.txt
$ ls -F backups/
bkp_dot_files/
$ mv dict words backups/
$ ls -F
backups/  low power adders/  word_lists/  words_ref.txt
$ ls -F backups/
bkp_dot_files/  dict/  words
  • Comme la commande cp, pour un seul fichier/dossier, il est possible de fournir un nom différent pour la destination.
  • Quand la source et la destination sont dans le même dossier, mv agit comme une commande de renommage.
 
Sélectionnez
$ mv backups/bkp_dot_files backups/dot_files
$ ls -F backups/
dict/  dot_files/  words

lectures supplémentaires

3-10. rename

Renomme un ou plusieurs fichiers

La commande rename basée sur Perl est présentée ici. Elle est différente de la version util-linux-ng. voir man rename pour les détails.

 
Sélectionnez
$ ls
backups  low power adders  word_lists  words_ref.txt

$ # ici le glob * va être étendu à tous les fichiers du dossier  courant non cachés.
$ # l'option -n permettra de faire une simulation 
$ # s/ /_/g signifie remplacer tous les caractères espace par le caractère _
$ rename -n 's/ /_/g' *
rename(low power adders, low_power_adders)
$ rename 's/ /_/g' *
$ ls
backups  low_power_adders  word_lists  words_ref.txt

lecture supplémentaire

3-11. ln

Crée un lien entre deux fichiers.

  • Il y a deux types de liens : les liens symboliques et les hard links.
  • les liens symboliques sont comme un pointeur/raccourci vers un autre fichier ou dossier.

    • si le fichier original est supprimé ou déplacé, le lien symbolique ne sera plus fonctionnel ;
    • si le lien symbolique est déplacé, il fonctionnera toujours s’il a été fait via un chemin absolu (pour un chemin relatif, cela dépendra de son endroit de déplacement) ;
    • un lien symbolique est un fichier qui a son propre inode, ses propres permissions, sa propre date, etc. ;
    • La plupart des commandes fonctionnent de la même façon pour un lien symbolique ou son fichier originel, voir leurs documentations pour plus de détails.
 
Sélectionnez
$ # comme pour cp, un nom différent peut être spécifié si requis
$ ln -s /usr/share/dict/words .
$ ls -F
words@
$ # pour savoir vers quel fichier pointe le lien
$ ls -l words
lrwxrwxrwx 1 learnbyexample eg 21 Jul  9 13:41 words -> /usr/share/dict/words
$ readlink words
/usr/share/dict/words
$ # le fichier lié peut être un autre lien
$ # utilisez l'option-f pour obtenir le fichier original
$ readlink -f words
/usr/share/dict/english
  • Un hard link peut seulement pointer vers un autre fichier (pas un dossier, et restreint au même système de fichiers)

    • les dossiers spéciaux . et .. sont l’exception, ce sont des hard links créés automatiquement.
  • Une fois un hard link créé, il n’y a pas de distinction entre les deux fichiers mis à part leurs différents noms et emplacements. Ils ont la même inode, les mêmes permissions, la même date, etc.
  • N’importe quel hard link continue de fonctionner tant que tous les hard links ne sont pas supprimés (NDLR on considérera le fichier d’origine comme un des hard links).
  • Si un hard link est déplacé vers un autre emplacement, les liens resteront synchronisés. Tout changement dans l’un d’eux sera reflété dans tous les autres liens.
 
Sélectionnez
$ touch foo.txt
$ ln foo.txt baz.txt
$ # l'option -i donne l'inode
$ ls -1i foo.txt baz.txt
649140 baz.txt
649140 foo.txt

lecture supplémentaire

3-12. tar et gzip

  • tar (Tape Archiver) est un utilitaire d’archive.
  • Voyons tout d’abord un exemple de création d’archives contenant plusieurs fichiers.
  • Notez que le fichier d’archive est un nouveau fichier qui ne supprime pas les fichiers source.
 
Sélectionnez
$ ls -F
backups/  low_power_adders/  word_lists/  words_ref.txt
$ # l’option -c crée une nouvelle archive, une archive existante au même nom sera écrasée
$ # l'option -f permet de spécifier le nom de l'archive à créer
$ # le reste des arguments sont les fichiers à archiver
$ tar -cf bkp_words.tar word_lists words_ref.txt
$ ls -F
backups/  bkp_words.tar  low_power_adders/  word_lists/  words_ref.txt
$ ls -sh bkp_words.tar
2.3M bkp_words.tar
  • Une fois que nous avons une archive, nous pouvons la compresser en utilisant gzip.
  • gzip remplace le fichier d’archive avec la version compressée en y ajoutant le suffixe .gz.
 
Sélectionnez
$ gzip bkp_words.tar
$ ls -F
backups/  bkp_words.tar.gz  low_power_adders/  word_lists/  words_ref.txt
$ ls -sh bkp_words.tar.gz
652K bkp_words.tar.gz
  • Pour décompresser, utilisez gunzip ou gzip -d.
  • Ceci remplacera la version compressée avec le fichier d’archive décompressé.
 
Sélectionnez
$ gunzip bkp_words.tar.gz
$ ls -F
backups/  bkp_words.tar  low_power_adders/  word_lists/  words_ref.txt
$ ls -sh bkp_words.tar
2.3M bkp_words.tar
  • pour extraire les fichiers source de l’archive, utilisez l’option -x.
 
Sélectionnez
$ mkdir test_extract
$ mv bkp_words.tar test_extract/
$ cd test_extract/
$ ls
bkp_words.tar
$ tar -xf bkp_words.tar
$ ls -F
bkp_words.tar  word_lists/  words_ref.txt
$ cd ..
$ rm -r test_extract/
  • la version GNU de tar supporte les options de compression/décompression.
 
Sélectionnez
$ ls -F
backups/  low_power_adders/  word_lists/  words_ref.txt
$ # l'option -z donne la même compression que la commande gzip
$ # la commande inverse serait : tar -zxf bkp_words.tar.gz
$ tar -zcf bkp_words.tar.gz word_lists words_ref.txt
$ ls -sh bkp_words.tar.gz
652K bkp_words.tar.gz
  • Il y a des tas d’options pour des besoins variés, voir la documentation pour les détails :

    • -v pour option verbeuse ;
    • -r pour ajouter des fichiers à l’archive ;
    • -t pour lister le contenu de l’archive ;
    • --exclude= pour spécifier les fichiers à ignorer lors de l’archivage ;
    • -j et -J pour utiliser les techniques de compression bzip2 ou xz à la place de -z qui utilise gzip.
  • Il y a des commandes commençant par z pour travailler avec des fichiers compressés :

    • zcat pour afficher le contenu des fichiers compressés sur la sortie standard ;
    • zless pour afficher le contenu des fichiers compressés une page à la fois ;
    • zgrep pour chercher dans des fichiers compressés, etc.

lecture supplémentaire

4. Travailler avec des fichiers ou des dossiers

Dans ce chapitre, nous allons, voir comment afficher le contenu de fichiers, chercher dedans, chercher des fichiers, obtenir leurs propriétés et informations, leurs permissions, et comment les changer selon nos besoins.

4-1. cat

(conCAT) Concatène les fichiers et les affiche sur la sortie standard.

Options

  • -n numérote les lignes à la sortie ;
  • -s compresse les lignes vides répétées en une seule ligne vide ;
  • -e affiche les caractères non imprimables et les fins de ligne ;
  • -A en addition à -e, montre aussi les caractères de tabulation.

Exemples

  • Un ou plusieurs fichiers peuvent être donnés en entrée, cat est utilisé pour afficher rapidement le contenu de simples petits fichiers sur le terminal,

  • Pour sauvegarder la sortie de la concaténation, redirigez juste stdout.
 
Sélectionnez
$ ls
marks_2015.txt  marks_2016.txt  marks_2017.txt
$ cat marks_201*
Name    Maths   Science
foo     67      78
bar     87      85
Name    Maths   Science
foo     70      75
bar     85      88
Name    Maths   Science
foo     68      76
bar     90      90
$ # sauve stdout dans un fichier
$ cat marks_201* > all_marks.txt
  • une option souvent utilisée est -A pour voir les caractères non imprimables et les caractères de fin de ligne.
 
Sélectionnez
$ printf 'foo\0bar\tbaz  \r\n'
foobar  baz
$ printf 'foo\0bar\tbaz  \r\n' | cat -A
foo^@bar^Ibaz  ^M$
  • utilisez tac pour afficher dans l’ordre inverse.
 
Sélectionnez
$ tac marks_2015.txt
bar     87      85
foo     67      78
Name    Maths   Science
$ seq 3 | tac
3
2
1

lecture supplémentaire

4-2. less

Opposé de more

La commande cat n’est pas adaptée à la lecture de gros fichiers sur le terminal. less affiche le contenu des fichiers, et adapte automatiquement son affichage à la taille du terminal, permettant le scrolling dans les deux sens et autres options pour une visualisation efficace. D’habitude, la commande man utilise la commande less pour afficher les pages d’aide. Les options de navigation sont similaires à l’éditeur vi.

Les commandes communément utilisées sont données ci-dessous, pressez h pour avoir un résumé des options.

  • g va au début du fichier ;
  • G va à la fin du fichier ;
  • q quitte ;
  • / recherche vers l’avant pour le motif donné ;
  • ? recherche vers l’arrière pour le motif donné ;
  • n va a motif suivant ;
  • N va au motif précédent.

Exemples et lecture supplémentaire

4-3. tail

Sort la dernière partie des fichiers

Exemples

  • Par défaut, tail affiche les dix dernières lignes.
  • Utilisez l’option -n pour changer le nombre de lignes souhaitées.
 
Sélectionnez
$ # les deux dernières lignes
$ tail -n2 report.log
Error: something seriously went wrong
blah blah blah
$ # toutes les lignes commençant à la troisième ligne c'est-à-dire toutes les lignes sauf les deux premières
$ seq 13 17 | tail -n +3
15
16
17
  • entrées de fichier multiples
 
Sélectionnez
$ # utilisez l'option -q pour éviter la sortie du nom de fichier
$ tail -n2 report.log sample.txt
==> report.log <==
Error: something seriously went wrong
blah blah blah
==> sample.txt <==
He he he
Adios amigo
  • extraction par caractère

    • Notez que cela fonctionne à l’échelle de l’octet et n’est pas adapté à des encodages de caractères à plusieurs octets.
 
Sélectionnez
Les trois derniers caractères en incluant le retour chariot
$ echo 'Hi there!' | tail -c3
e!
$ # exclusion du premier caractère
$ echo 'Hi there!' | tail -c +2
i there!

Lecture supplémentaire

4-4. head

Sort la première partie des fichiers

Exemples

  • Par défaut, head affiche les dix premières lignes.
  • Utilisez l’option -n pour changer le nombre de lignes voulues.
 
Sélectionnez
$ head -n3 report.log
blah blah
Warning: something went wrong
more blah
$ # tail donne les dix dernières lignes, puis head donne les deux premières de la sortie de tail
$ tail sample.txt | head -n2
Just do-it
Believe it
$ # excepté les 2 dernières lignes
$ seq 13 17 | head -n -2
13
14
15
  • entrée de fichiers multiples
 
Sélectionnez
$ # utilisez l'option -q pour éviter le nom de fichier dans la sortie
$ head -n3 report.log sample.txt 
==> report.log <==
blah blah
Warning: something went wrong
more blah
==> sample.txt <==
Hello World!
Good day
  • extraction par caractère

    • Notez que cela fonctionne à l’échelle de l’octet et n’est pas adapté à des encodages de caractères à plusieurs octets.
 
Sélectionnez
$ # les deux premiers caractères
$ echo 'Hi there!' | head -c2
Hi
$ # exclusion des quatre derniers caractères
$ echo 'Hi there!' | head -c -4
Hi the

Lecture supplémentaire

4-5. Éditeurs de texte

Pour éditer des fichiers texte, les applications suivantes peuvent être utilisées. De celles-ci, gedit, nano, vi et/ou vim sont disponibles par défaut dans la plupart des distributions.

Facile à utiliser :

Éditeurs de texte puissants :

4-6. grep

Affiche les lignes correspondant à un motif.

grep signifie « Global Regular Expression Print. » Utilisé pour chercher un motif dans les fichiers indiqués, qu’il s’agisse d’un mot particulier ou d’un motif présent/absent, des noms de fichiers contenant le motif, etc. Par défaut, la correspondance est faite dans n’importe quelle partie d’une ligne, les options et expressions régulières peuvent être utilisées pour faire la recherche.

Options

  • --color=auto affiche les motifs correspondants, les noms de fichier, les numéros de ligne, etc. avec une distinction de couleur.
  • -i ignore la casse pendant la recherche de correspondance ;
  • -v affiche les lignes ne correspondant pas, c’est-à-dire inverse la sélection ;
  • -n affiche aussi les numéros de ligne des motifs correspondants ;
  • -c affiche seulement le décompte de nombre de lignes correspondant au motif :
  • -l affiche seulement le nom des fichiers correspondant au motif ;
  • -L affiche le nom des fichiers ne correspondant pas au motif ;
  • -w affiche les correspondances seulement pour les mots entiers ;
  • -x affiche les correspondances seulement pour les lignes entières ;
  • -F interprète le motif comme une chaîne fixe (c’est-à-dire : pas comme une expression régulière), plus vite aussi ;
  • -o affiche seulement les parties correspondant ;
  • -A affiche le nombre de lignes correspondant et le nombre de lignes après ;
  • -B affiche le nombre de lignes correspondant et le nombre de lignes avant ;
  • -C affiche le nombre de lignes correspondant et le nombre de lignes avant et après ;
  • -m arrête la lecture après le nombre de lignes correspondant spécifié ;
  • -q pas de sortie, quitte immédiatement si pas de correspondance. Pratique dans des scripts pour vérifier si un fichier contient un motif correspondant ;
  • -s supprime les messages d’erreur si le fichier n’existe pas ou n’est pas lisible, encore une fois, pratique dans les scripts ;
  • -r recherche récursive dans tous les fichiers du dossier spécifié ;
  • -h ne préfixe pas la/les ligne(s) correspondant au nom de fichier (comportement par défaut pour une recherche dans un seul fichier) ;
  • -H préfixe la/les ligne(s) correspondant au nom de fichier (comportement par défaut pour une recherche dans plusieurs fichiers).

Exemples

  • grep 'area' report.log va afficher toutes les lignes contenant le mot « area » dans report.log ;
  • grep 'adder power' report.log va afficher toutes les lignes contenant « adder power » ;
  • man grep | grep -i -A 5 'code de sortie' va afficher les lignes correspondant et 5 lignes après contenant les mots « exit status » indépendamment de la casse :

    • Voir le sujet Context Line Control dans info grep pour les options en relation telles que --no-group-separator.
  • grep -m 5 'error' report.log va afficher un maximum de cinq lignes contenant le mot « error » ;
  • grep "$HOME" /,etc./passwd va afficher les lignes correspondant à la valeur de la variable d’environnement HOME ;

    • Notez l’usage des guillemets pour la substitution de variable.
  • grep -w 'or' story.txt correspond au mot entier ou ne fait pas partie du mot comme pour, épine, etc. ;
  • grep -x 'power' test_list.txt correspond à toute la ligne contenant le motif « power » ;

Note:

Tous les exemples ci-dessus devraient être appropriés pour l’option -F option comme ceux n’utilisant pas d’expression régulière et seront plus rapides avec celle-ci.

Expressions régulières

Les expressions régulières aident à définir des mots de recherche précis, comme extraire uniquement des caractères alphabétiques ou des nombres, correspondance avec début de ligne, fin de ligne, séquences de caractères, etc.
Les références suivantes sont pour ERE - Extended Regular Expressions

Ancres :

  • ^ correspondance avec le début de ligne ;
  • $ correspondance avec la fin de ligne ;
  • \< correspondance avec le début de mot ;
  • \> correspondance avec la fin de mot ;
  • \b correspondance avec la limite de mot ;
  • \B inverse de \b.

Quantificateurs de caractères :

  • . correspond à tout caractère simple ;
  • * correspond au caractère précédent 0 fois ou plus ;
  • + correspond au caractère précédent 1 fois ou plus ;
  • ? correspond au caractère précédent 0 ou 1 fois ;
  • {n} correspond au caractère précédent exactement n fois ;
  • {n,} correspond au caractère précédent n fois ou plus ;
  • {n,m} correspond au caractère précédent de n à m fois (inclus n et m) ;
  • {,m} correspond au caractère précédent jusqu’à n fois ;

Classes de caractères :

  • [aeiou] correspond à n’importe lequel de ces caractères ;
  • [^aeiou] ne correspond à aucun de ces caractères ;
  • [a-z] correspond à n’importe quel caractère de l’alphabet ;
  • [0-9] correspond à n’importe quel caractère numérique ;
  • \w correspond à tout caractère, alphanumérique, et au caractère underscore, raccourci pour [a-zA-Z0-9_] ;
  • \W opposé à \w , raccourci pour [^a-zA-Z0-9_] ;
  • \s correspond aux caractères invisibles: tabulation, retour chariot, tabulation verticale, espace ;
  • \S inverse de \s.

Groupes de modèles :

  • | correspond à l’un des modèles donnés ;
  • () les motifs entre () sont regroupés et traités comme un seul motif, utile en conjonction avec | ;
  • \1 référence arrière au premier motif groupé dans () ;
  • \2 référence arrière au second motif groupé dans (), etc.

Expressions régulières basiques versus les expressions régulières étendues

Par défaut, les motifs passés à grep sont traités comme des expressions régulières basiques (Basic Regular Expressions : BRE), ce qui peut être modifié en utilisant les options comme -E for ERE et -P pour Perl Compatible Regular Expression (PCRE)
Paraphrase depuis info grep

Avec les expressions régulières basiques, les métacaractères ? + { | ( ) perdent leur signification spéciale, utilisez plutôt les versions avec antislash \? \+ \{ \| \( \)

Exemples

  • grep -i '[a-z]' report.log : imprime toutes les lignes ayant au moins un caractère alphabétique ;
  • grep '[0-9]' report.log : imprime toutes les lignes ayant au moins un caractère numérique ;
  • grep 'area\|power' report.log : correspond aux lignes contenant « area » ou « power » ;
  • grep -E 'area|power' report.log : correspond aux lignes contenant « area » ou « power » ;
  • grep -E 'hand(y|ful)' short_story.txt : correspond à « handy » ou « handful « ;
  • grep -E '(Th)?is' short_story.txt : correspond à « This » ou « is »
  • grep -iE '([a-z])\1' short_story.txt : correspond aux mêmes caractères alphabétiques apparaissant de façon consécutive comme « aa », « FF »', « Ee », etc.

Expression régulière compatible Perl :

  • grep -P '\d' report.log : affiche toutes les lignes ayant au moins un nombre ;
  • grep -P '(Th)?is' short_story.txt : correspond à « This » ou « is » ;
  • grep -oP 'file\K\d+' report.log : affiche seulement les chiffres précédés de la chaîne « file ».
  • man pcrepattern : syntaxe sémantique des expressions régulières supportées par PCRE ;
  • look-around assertions example

Exemple de fichiers d’entrée

 
Sélectionnez
$ cat ip.txt 
Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.

$ echo -e 'Red\nGreen\nBlue\nBlack\nWhite' > colors.txt
$ cat colors.txt
Red
Green
Blue
Black
White
  • recherche de chaîne, utilisation de -F pour des résultats plus rapides
 
Sélectionnez
$ grep -F 'are' ip.txt 
Roses are red,
Violets are blue,
And so are you.

$ grep -Fv 'are' ip.txt 
Sugar is sweet,

$ grep -Fc 'are' ip.txt 
3

$ grep -F -m2 'are' ip.txt 
Roses are red,
Violets are blue,

$ grep -F 'rose' ip.txt
$ grep -Fi 'rose' ip.txt
Roses are red,
  • expression regular, où on ne peut pas utiliser -F :
 
Sélectionnez
$ # lignes avec des mots commençant par s ou S
$ grep -iE '\bs' ip.txt 
Sugar is sweet,
And so are you.
$ # récupère seulement les mots commençant par s ou S
$ grep -ioE '\bs[a-z]+' ip.txt
Sugar
sweet
so
  • utilisation d’entrées de fichier pour spécifier les termes à rechercher :
 
Sélectionnez
$ grep -Fif colors.txt ip.txt 
Roses are red,
Violets are blue,

$ echo -e 'Brown\nRed\nGreen\nBlue\nYellow\nBlack\nWhite' > more_colors.txt 

$ # récupère les lignes communes entre deux fichiers
$ grep -Fxf colors.txt more_colors.txt 
Red
Green
Blue
Black
White
$ # récupère les lignes présentes dans more_colors.txt, mais pas dans colors.txt
$ grep -Fxvf colors.txt more_colors.txt
Brown
Yellow

Lecture supplémentaire

4-7. find

Recherche de fichiers dans une hiérarchie de dossiers.

Exemples

Filtrage basé sur le nom de fichier

  • find . -iname 'power.log' cherche et affiche le chemin du fichier nommé power.log (en ignorant la casse) dans le dossier courant et ses sous-dossiers ;
  • find -name '*log' cherche et imprime le chemin de tous les fichiers dont le nom se termine par log dans le dossier courant ; utiliser est optionnel quand on recherche dans le dossier en cours ;
  • find -not -name '*log' affiche le chemin de tous les fichiers du dossier courant dont le nom ne se termine PAS par log ;
  • find -regextype egrep -regex '.*/\w+' utilise les expressions régulières étendues pour faire correspondre le nom de fichier contenant seulement les caractères [a-zA-Z_] ;

    • .*/ est requis pour la correspondance de la partie initiale du chemin de fichier.

Filtrage basé sur le type de fichier :

  • find /home/guest1/proj -type f affiche le chemin des tous les fichiers réguliers trouvés dans le dossier spécifié ;
  • find /home/guest1/proj -type d affiche le chemin des tous les dossiers trouvés dans le dossier spécifié ;
  • find /home/guest1/proj -type f -name '.*' affiche le chemin de tous les fichiers cachés.

Filtrage basé sur la profondeur :

Le chemin relatif . est considéré comme un dossier de profondeur 0 , les fichiers et dossiers contenus dans un dossier sont à la profondeur 1, etc. ;

  • find -maxdepth 1 -type f tous les fichiers réguliers (les fichiers cachés inclus) du dossier courant (sans gérer les sous-dossiers) ;
  • find -maxdepth 1 -type f -name '[!.]*' tous les fichiers réguliers (mais pas les fichiers cachés) du dossier courant (sans gérer les sous-dossiers) ;

    • -not -name '.*' peut aussi être utilisé
  • find -mindepth 1 -maxdepth 1 -type d tous les dossiers (les dossiers cachés inclus) dans le dossier courant (sans gérer les sous-dossiers).

Filtrage basé sur les propriétés de fichier :

  • find -mtime -2 affiche les fichiers du dossier courant qui ont été modifiés ces deux derniers jours ;

    • Notez qu’ici un jour signifie 24 heures.
  • find -mtime +7 affiche les fichiers du dossier courant qui ont été modifiés il y a plus de 7 jours ;
  • find -daystart -type f -mtime -1 files affiche les fichiers modifiés depuis le début de la journée (pas plus de 24 heures) ;
  • find -size +10k affiche les fichiers du dossier courant plus grands que 10 kilooctets ;
  • find -size 1M affiche les fichiers du dossier courant plus grands qu’un mégaoctet ;
  • find -size 2G affiche les fichiers du dossier courant plus grands que 2 gigaoctets ;

passages de fichiers filtrés comme entrée d’autres commandes :

  • find report -name '*log*' exec rm {} \; supprime tous les fichiers contenant log dans leur nom dans le dossier « report » et ses sous-dossiers ;

    • ici la commande rm est appelée pour chaque fichier remplissant les conditions ;
    • comme ; est un caractère spécial pour le shell, il doit être échappé en utilisant \ ;
  • find report -name '*log*' -delete supprime tous les fichiers dont le nom contient « log » dans le dossier « report » et ses sous-dossiers ;
  • find -name '*.txt' -exec wc {} + liste tous les fichiers finissant par « txt », ils sont tous passés comme arguments à la commande wc plutôt que d’exécuter wc sur chaque fichier ;

    • pas besoin d’utiliser le caractère d’échappement pour le caractère + dans ce cas ;
    • notez également que le nombre d’invocations de la commande spécifiée n’est pas nécessairement unique si le nombre de fichiers trouvés est trop grand.
  • find -name '*.log' -exec mv {} ../log/ \; déplace les fichiers finissant par .log vers le dossier log présent dans une hiérarchie au-dessus. mv est exécuté une fois pour chaque fichier filtré ;
  • find -name '*.log' -exec mv -t ../log/ {} + l’option -t permet de spécifier le dossier de destination et permet donc le déplacement de plusieurs fichiers comme argument ;

    • de façon similaire, il est possible d’utiliser -t pour la commande cp.

Lecture supplémentaire

4-8. locate

Trouve des fichiers par leur nom.

C’est une solution plus rapide que la commande find lors de la recherche d’un fichier par son nom. Il est conçu autour d’une base de données, qui doit être mise à jour par un job cron. Les nouveaux fichiers ne seront donc pas présents dans les résultats. Utilisez cette commande si elle est disponible dans votre distribution et que vous vous rappelez une partie du nom du fichier. Très pratique en cas de besoin de recherche dans toute l’arborescence, qui dans ce cas sera très long avec la commande find par rapport à locate.

Exemples

  • locate 'power' affiche le chemin des fichiers contenant « power » dans tout le système de fichiers ;

    • correspond à n’importe où dans le chemin, ex. : /home/learnbyexample/lowpower_adder/result.log et /home/learnbyexample/power.log sont tous les deux des correspondances valides ;
    • implicitement, locate ne devrait pas changer la chaîne *power*, car il n’y pas de caractères de substitution dans la chaîne spécifiée.
  • locate -b '\power.log' affiche les chemins comportant exactement la chaîne « power.log » en fin de chemin ;

    • /home/learnbyexample/power.log correspond, mais pas /home/learnbyexample/lowpower.log ;
    • comme le caractère de substitution \ est utilisé lors de la spécification de la chaîne de recherche, il n’y pas de remplacement implicite par *power.log*.
  • locate -b '\proj_adder' l’option -b est également pratique pour seulement afficher le chemin d’un nom de dossier, sinon chaque fichier du dossier serait aussi affiché.
  • find vs locate - les avantages et inconvénients

NDLR La commande updatedb permet la mise à jour de la base de données utilisée par locate.

4-9. wc

Affiche les lignes, les mots, et la taille en octets pour chaque fichier.

Exemples

 
Sélectionnez
$ # par défaut, donne  nombre de nouvelles lignes/mot/compteur d'octets (dans cet ordre)
$ wc sample.txt 
 5 17 78 sample.txt

$ # options pour récupérer seulement nouvelles lignes, les mots, le nombre d'octets
$ wc -l sample.txt 
5 sample.txt
$ wc -w sample.txt 
17 sample.txt
$ wc -c sample.txt 
78 sample.txt
$ # utilisez la rediction entrée du shell si le nom de fichier n'est pas requis
$ wc -l < sample.txt
5
  • entrée de fichier multiple :
 
Sélectionnez
$ # affiche automatiquement le total à la fin
$ wc *.txt
  5  10  57 fruits.txt
  2   6  32 greeting.txt
  5  17  78 sample.txt
 12  33 167 total
  • autres options
 
Sélectionnez
$ # utiliser -L pour obtenir la longueur de la ligne la plus longue
$ # ne compte pas les caractères non imprimables, les tabulations sont converties en équivalents espaces
$ wc -L < sample.txt
24
$ printf 'foo\tbar\0baz' | wc -L
14
$ printf 'foo\tbar\0baz' | awk '{print length()}'
11
$ # -c gives byte count, -m gives character count
$ printf 'hi👍' | wc -m
3
$ printf 'hi👍' | wc -c
6

lecture supplémentaire

4-10. du

Estimation de utilisation d’espaces par les fichiers.

Exemples

 
Sélectionnez
$ # Par défaut, la taille est donnée en multiples de 1024 octets.
$ # Les fichiers sont ignorés, tous les dossiers et sous-dossiers sont reportés récursivement
$ # ajoutez l'option -a si les fichiers sont aussi requis et -L si les liens doivent être déréférencés

$ du
17920   ./projs/full_addr
14316   ./projs/half_addr
32952   ./projs
33880   .
$ # utiliser -s pour montrer la taille totale d'un dossier sans descendre dans les sous-dossiers
$ # ajouter -c pour montrer également la taille à la fin
$ du -s projs words.txt
32952   projs
924     words.txt
  • les différentes options de formatage de taille :
 
Sélectionnez
$ # nombres d'octets
$ du -b words.txt
938848  words.txt

$ # kilooctet = 1024 octets
$ du -sk projs
32952   projs

$ # megaoctet = 1024 kiloctets
$ du -sm projs
33      projs
$ # human readable, utiliser --si pour des puissances de 1000 à la place de 1024
$ du -h words.txt
924K    words.txt
$ # tri
$ du -sh projs/* words.txt | sort -h
712K    projs/report.log
924K    words.txt
14M     projs/half_addr
18M     projs/full_addr

lecture supplémentaire

4-11. df

Retourne l’utilisation disque au niveau filesystem.

Exemples

 
Sélectionnez
$ # utiliser df sans argument pour obtenir l'information sur tous les filesystem montés

$ df .
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda1       98298500 58563816  34734748  63% /
$ # utiliser l'option -B pour une taille personnalisée
$ # utiliser --si pour des puissances de 1000 à la place de 1024
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        94G   56G   34G  63% /
  • Utiliser --output pour retourner seulement les champs qui vous intéressent
 
Sélectionnez
$ df -h --output=size,used,file / /media/learnbyexample/projs
 Size  Used File
  94G   56G /
  92G   35G /media/learnbyexample/projs
$ df -h --output=pcent .
Use%
 63%
$ df -h --output=pcent,fstype | awk -F'%' 'NR>2 && $1>=40'
 63% ext3
 40% ext4
 51% ext4

lecture supplémentaire

4-12. touch

change les dates d’accès à un fichier.

Exemples

 
Sélectionnez
$ # dernière date d'accès et modification
$ stat -c $'%x\n%y' fruits.txt
2017-07-19 17:06:01.523308599 +0530
2017-07-13 13:54:03.576055933 +0530

$ # mise à jour du timestamp accès et modification au timestamp de la date et heure actuelles
$ # ajouter -a pour changer seulement la date d'accès et -m pour changer seulement la modification
$ touch fruits.txt
$ stat -c $'%x\n%y' fruits.txt
2017-07-21 10:11:44.241921229 +0530
2017-07-21 10:11:44.241921229 +0530
$ # copie le timestamp d'accès et de modification de power.log vers report.log
$ # ajouter -a ou -m si nécessaire
$ # voir aussi les options -d et -t
$ touch -r power.log report.log
  • si le fichier n'existe pas, un fichier vide est créé sauf si -c est utilisé.
 
Sélectionnez
$ ls foo.txt
ls: cannot access 'foo.txt': No such file or directory
$ touch foo.txt
$ ls foo.txt
foo.txt

lecture supplémentaire

4-13. file

détermine le type d’un fichier.

Exemples

 
Sélectionnez
$ file sample.txt 
sample.txt: ASCII text
$ printf 'hi👍\n' | file -
/dev/stdin: UTF-8 Unicode text
$ file ch
ch:  Bourne-Again shell script, ASCII text executable
$ printf 'hi\r\n' | file -
/dev/stdin: ASCII text, with CRLF line terminators
$ file sunset.jpg moon.png
sunset.jpg: JPEG image data
moon.png: PNG image data, 32 x 32, 8-bit/color RGBA, non-interlaced
  • Trouver tous les fichiers d'un type particulier dans le dossier courant, par exemple des fichiers image :
 
Sélectionnez
$ find -type f -exec bash -c '(file -b "$0" | grep -wq "image data") && echo "$0"' {} \;
./sunset.jpg
./moon.png
$ # si les fichiers ne contiennent pas de caractère : ou de retour chariot
$ find -type f -exec file {} + | awk -F: '/\<image data\>/{print $1}'
./sunset.jpg
./moon.png

lecture supplémentaire

  • Pour plus d’exemples détaillés et des discussions, voir file from command line text processing repo
  • Voir aussi la commande identify qui décrit le format et les caractéristiques de plusieurs types de fichiers image.

4-14. basename

Découpe le suffixe correspondant au dossier dans un nom de fichier.

Exemples

 
Sélectionnez
$ # identique à l'utilisation de la commande pwd
$ echo "$PWD"
/home/learnbyexample

$ basename "$PWD"
learnbyexample
$ # utiliser l'option -a s'il y a plusieurs arguments
$ basename -a foo/a/report.log bar/y/power.log
report.log
power.log
$ # utiliser les guillemets simples si les arguments contiennent des espaces ou autres caractères spéciaux du shell
$ # utiliser l'option de suffixe -s pour séparer l'extension de fichier de son nom
$ basename -s '.log' '/home/learnbyexample/proj adder/power.log'
power
$ # -a est implicite lors de l'utilisation de l'option-s
$ basename -s'.log' foo/a/report.log bar/y/power.log
report
power

4-15. dirname

Retire le dernier composant d’un nom de fichier pour extraire le dossier qui le contient.

Exemples

 
Sélectionnez
$ echo "$PWD"
/home/learnbyexample

$ dirname "$PWD"
/home

$ # utiliser les guillemets simples si les arguments contiennent des espaces ou autres caractères spéciaux du shell
$ dirname '/home/learnbyexample/proj adder/power.log'
/home/learnbyexample/proj adder
$ # contrairement à basename, par défaut, dirname gère des arguments multiples
$ dirname foo/a/report.log bar/y/power.log
foo/a
bar/y
$ # s'il n'y a pas de / dans l'argument, la sortie est . Pour indiquer le dossier courant
$ dirname power.log
$ .

4-16. chmod

change les bits des droits d’accès.

 
Sélectionnez
$ ls -l sample.txt
-rw-rw-r-- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt

Dans la sortie de la commande ls -l précédente, les dix premiers caractères affichés correspondent au type du fichier et à ses permissions.

Le premier caractère indique le type de fichier. Les plus communs sont :

  • - fichier régulier ;
  • d dossier ;
  • l lien symbolique ;
  • pour la liste complète, voir l’option -l dans info ls.

Les neuf autres caractères représentent trois ensembles de permission de fichiers, pour l’utilisateur, le groupe, et les autres, dans cet ordre :

  • les propriétés user pour le propriétaire du fichier -u.
  • les propriétés group pour le groupe auquel le fichier appartient -g.
  • others les propriétés de tous les autres utilisateurs -o.

Nous ne verrons dans cette section que les propriétés rwx, pour les autres types de propriétés, référez-vous à la documentation détaillée.

Valeurs des caractères de permission

Caractère

Signification

Valeur

Fichier

Dossier

r

lecture

4

Le fichier peut être lu

Peut voir le contenu du dossier

w

écriture

2

Le fichier peut être modifié

Peut ajouter/supprimer des fichiers dans le dossier

x

exécution

1

Le fichier peut être lancé en tant que programme

Peut accéder au contenu du dossier

-

aucune permission

0

Aucune permission

Aucune permission

Permissions de fichiers

 
Sélectionnez
$ pwd
/home/learnbyexample/linux_tutorial
$ ls -lF
total 8
-rw-rw-r-- 1 learnbyexample learnbyexample  40 May 28 13:25 hello_world.pl
-rw-rw-r-- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt

$ # les fichiers nécessitent la permission exécution pour pouvoir être lancés comme un programme

$ ./hello_world.pl
bash: ./hello_world.pl: Permission denied
$ chmod +x hello_world.pl 
$ ls -lF hello_world.pl
-rwxrwxr-x 1 learnbyexample learnbyexample  40 May 28 13:25 hello_world.pl*
$ ./hello_world.pl
Hello World

$ # permission de lecture
$ cat sample.txt 
This is an example of adding text to a new file using cat command.
Press Ctrl+d on a newline to save and quit.
$ chmod -r sample.txt
$ ls -lF sample.txt 
--w--w---- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt
$ cat sample.txt 
cat: sample.txt: Permission denied

$ #Les fichiers nécessitent la permission en écriture pour pouvoir être modifiés
$ cat >> sample.txt 
Adding a line of text at end of file
^C
$ cat sample.txt 
cat: sample.txt: Permission denied
$ chmod +r sample.txt 
$ ls -lF sample.txt 
-rw-rw-r-- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt
$ cat sample.txt 
This is an example of adding text to a new file using cat command.
Press Ctrl+d on a newline to save and quit.
Adding a line of text at end of file
$ chmod -w sample.txt 
$ ls -lF sample.txt
-r--r--r-- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt
$ cat >> sample.txt
bash: sample.txt: Permission denied

Permissions de dossiers

 
Sélectionnez
$ ls -ld linux_tutorial/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/

$ #Permission de lecture
$ ls linux_tutorial/
hello_world.pl  sample.txt
$ chmod -r linux_tutorial/
$ ls -ld linux_tutorial/
d-wx-wx--x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ ls linux_tutorial/
ls: cannot open directory linux_tutorial/: Permission denied
$ chmod +r linux_tutorial/
$ #Permission d’exécution
$ chmod -x linux_tutorial/
$ ls -ld linux_tutorial/
drw-rw-r-- 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ ls linux_tutorial/
ls: cannot access linux_tutorial/hello_world.pl: Permission denied
ls: cannot access linux_tutorial/sample.txt: Permission denied
hello_world.pl  sample.txt
$ chmod +x linux_tutorial/
$ #Permission d'écriture
$ chmod -w linux_tutorial/
$ ls -ld linux_tutorial/
dr-xr-xr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ touch linux_tutorial/new_file.txt
touch: cannot touch ‘linux_tutorial/new_file.txt’: Permission denied
$ chmod +w linux_tutorial/
$ ls -ld linux_tutorial/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ touch linux_tutorial/new_file.txt
$ ls linux_tutorial/
hello_world.pl  new_file.txt  sample.txt

Changer plusieurs permissions en une fois

 
Sélectionnez
$ # r(4) + w(2) + 0 = 6
$ # r(4) + 0 + 0 = 4
$ chmod 664 sample.txt 
$ ls -lF sample.txt 
-rw-rw-r-- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt

$ # r(4) + w(2) + x(1) = 7
$ # r(4) + 0 + x(1) = 5
$ chmod 755 hello_world.pl 
$ ls -lF hello_world.pl
-rwxr-xr-x 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl*
$ chmod 775 report/
$ ls -ld report/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 14:01 report/

Changer une permission unique de façon sélective

 
Sélectionnez
$ chmod o-r sample.txt 
$ ls -lF sample.txt 
-rw-rw---- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt

$ chmod go-x hello_world.pl 
$ ls -lF hello_world.pl 
-rwxr--r-- 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl*

$ chmod go+x hello_world.pl
$ ls -lF hello_world.pl
-rwxr-xr-x 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl*

Changer récursivement les permissions d’un dossier

 
Sélectionnez
$ ls -lR linux_tutorial/
linux_tutorial/:
total 12
-rwxr-xr-x 1 learnbyexample learnbyexample   40 May 28 13:25 hello_world.pl
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 14:32 report
-rw-rw---- 1 learnbyexample learnbyexample  148 May 29 11:00 sample.txt

linux_tutorial/report:
total 0
-rw-rw-r-- 1 learnbyexample learnbyexample 0 May 29 11:46 new_file.txt
$ ls -ld linux_tutorial/
drwxrwxr-x 3 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/

$ #adding/removing files to a directory depends only on parent directory permissions
$ chmod -w linux_tutorial/
$ ls -ld linux_tutorial/
dr-xr-xr-x 3 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/
$ ls -ld linux_tutorial/report/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/report/
$ rm linux_tutorial/sample.txt 
rm: cannot remove ‘linux_tutorial/sample.txt’: Permission denied
$ touch linux_tutorial/report/power.log
$ ls linux_tutorial/report/
new_file.txt  power.log
$ rm linux_tutorial/report/new_file.txt
$ ls linux_tutorial/report/
power.log

$ chmod +w linux_tutorial/
$ ls -ld linux_tutorial/
drwxrwxr-x 3 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/
$ chmod -w -R linux_tutorial/
$ ls -lR linux_tutorial/
linux_tutorial/:
total 12
-r-xr-xr-x 1 learnbyexample learnbyexample   40 May 28 13:25 hello_world.pl
dr-xr-xr-x 2 learnbyexample learnbyexample 4096 May 29 14:40 report
-r--r----- 1 learnbyexample learnbyexample  148 May 29 11:00 sample.txt
linux_tutorial/report:
total 0
-r--r--r-- 1 learnbyexample learnbyexample 0 May 29 14:39 power.log
$ rm linux_tutorial/report/power.log
rm: remove write-protected regular empty file ‘linux_tutorial/report/power.log’? y
rm: cannot remove ‘linux_tutorial/report/power.log’: Permission denied
  • La façon dont les permissions sont affectées par +-/rwx dépend de la valeur de umask, qui est habituellement 002 qui signifie :

    • +r -r +x -x sans les qualificateurs u g o affecte les trois catégories ;
    • +w -w sans les qualificateurs u g o qualifiés affecte seulement les catégories user et group.

Lecture supplémentaire

L’ensemble riche de commandes de traitement de texte est complet et vous fera gagner du temps. Sachant que même leur existence est suffisante pour éviter l’écriture d’un autre script (ce qui prend du temps et demande des efforts, en plus du débogage) ; un piège dans lequel tombent de nombreux débutants. Une liste étendue de commandes de traitements de texte et des exemples peuvent être trouvés ici.

5. Traitement de texte

5-1. sort

Trie les lignes de fichiers texte

Comme le nom le sous-entend, cette commande est utilisée pour trier des fichiers. Qu'en est-il du tri alphabétique et numérique ? Il est possible. Et le tri de colonnes particulières ? Possible. Et l’ordre de tri priorisé ? Possible. Aléatoire ? Unique ? Presque tous les types de tris sont pris en charge par cette commande puissante.

Options

  • -R tri aléatoire ;
  • -r tri en ordre inverse ;
  • -o redirige le résultat du tri dans un fichier spécifié, très pratique pour trier un fichier existant ;
  • -n tri numérique ;
  • -V tri numérique par version ;
  • -h tri par numéros humainement lisibles ;
  • -b ignore les espaces de début et fin de ligne lors du tri.

Exemples

  • sort dir_list.txt affiche le fichier trié sur la sortie standard ;
  • sort -bn numbers.txt -o numbers.txt trie « numbers.txt » numériquement (en ignorant les espaces de début et fin) et en écrasant le fichier avec la sortie triée ;
  • sort -R crypto_keys.txt -o crypto_keys_random.txt trie de façon aléatoire et écrit dans un nouveau fichier ;

    • shuf crypto_keys.txt -o crypto_keys_random.txt peut aussi être utilisé
  • du -sh * | sort -h trie les tailles de fichiers/répertoires dans le dossier courant et dans un format lisible humainement.
 
Sélectionnez
$ cat ip.txt 
6.2  : 897 : bar
3.1  : 32  : foo
2.3  : 012 : bar
1.2  : 123 : xyz

$ # -k3,3 signifie de la troisième colonne à partir de la 3e colonne
$ # par ex-: pour trier de la seconde colonne jusqu'à la fin, utilisez -k2
$ sort -t: -k3,3 ip.txt 
2.3  : 012 : bar
6.2  : 897 : bar
3.1  : 32  : foo
1.2  : 123 : xyz

$ # l'option -n pour un tri numérique, regardez ce qui se passe quand  -n n'est pas utilisé
$ sort -t: -k2,2n ip.txt 
2.3  : 012 : bar
3.1  : 32  : foo
1.2  : 123 : xyz
6.2  : 897 : bar
$ #plus d'une règle peut être spécifiée pour résoudre les mêmes valeurs
$ sort -t: -k3,3 -k1,1rn ip.txt
6.2  : 897 : bar
2.3  : 012 : bar
3.1  : 32  : foo
1.2  : 123 : xyz

Lecture supplémentaire

5-2. uniq

Signale ou omet les lignes répétées.

Cette commande est plus spécifique pour reconnaître les lignes dupliquées. Nécessite habituellement une entrée triée, car la comparaison se fait sur des lignes contigues.

Options :

  • -d affiche seulement les lignes dupliquées ;
  • -c préfixe par le nombre d’occurrences ;
  • -u affiche seulement les lignes uniques.

Exemples :

  • sort test_list.txt | uniq affiche les lignes de « test_list.txt » triées avec les lignes en double supprimées ;

    • uniq <(sort test_list.txt) la même commande en utilisant un processus de substitution ;
    • sort -u test_list.txt est une commande équivalente.
  • uniq -d sorted_list.txt affiche seulement les lignes en double ;
  • uniq -cd sorted_list.txt affiche seulement les lignes en double,avec en préfixe le nombre d’occurrences ;
  • uniq -u sorted_list.txt affiche seulement les lignes uniques, les lignes répétées sont ignorées.
  • uniq Q&A on unix stackexchange
 
Sélectionnez
$ echo -e 'Blue\nRed\nGreen\nBlue\nRed\nBlack\nRed' > colors.txt 
$ uniq colors.txt 
Blue
Red
Green
Blue
Red
Black
Red

$ echo -e 'Blue\nRed\nGreen\nBlue\nRed\nBlack\nRed' | sort > sorted_colors.txt 
$ uniq sorted_colors.txt
Black
Blue
Green
Red

$ uniq -d sorted_colors.txt 
Blue
Red

$ uniq -cd sorted_colors.txt 
      2 Blue
      3 Red
$ uniq -u sorted_colors.txt
Black
Green

5-3. comm

Compare deux fichiers triés ligne par ligne.

Sans aucune option, affiche sur les données sur trois colonnes, lignes uniques du fichier 1, lignes uniques du fichier 2, et les lignes communes aux deux fichiers.

Options :

  • -1 supprime les lignes uniques au fichier 1 ;
  • -2 supprime les lignes uniques au fichier 2 ;
  • -3 supprime les lignes communes aux deux fichiers.

Exemples :

  • comm -23 sorted_file1.txt sorted_file2.txt affiche les lignes uniques de sorted_file1.txt ;

    • comm -23 <(sort file1.txt) <(sort file2.txt) même commande en utilisant la substitution de processus, si des fichiers en entrée ne sont pas disponibles.
  • comm -13 sorted_file1.txt sorted_file2.txt affiche les lignes uniques de sorted_file2.txt ;
  • comm -12 sorted_file1.txt sorted_file2.txt affiche les lignes communes aux deux fichiers.
  • comm Q&A on unix stackexchange
 
Sélectionnez
$ echo -e 'Brown\nRed\nPurple\nBlue\nTeal\nYellow' | sort > colors_1.txt
$ echo -e 'Red\nGreen\nBlue\nBlack\nWhite' | sort > colors_2.txt
$ # les fichiers d'entrée vus côte à côte
$ paste colors_1.txt colors_2.txt
Blue    Black
Brown   Blue
Purple  Green
Red     Red
Teal    White
Yellow
  • exemples
 
Sélectionnez
$ # 3 colonnes en sortie - unique au fichier 1, au fichier 2,et les lignes communes
$ comm colors_1.txt colors_2.txt
        Black
                Blue
Brown
        Green
Purple
                Red
Teal
        White
Yellow 

$ # supprime la colonne 1 et 2, donne seulement les lignes communes
$ comm -12 colors_1.txt colors_2.txt
Blue
Red
$ # supprime les colonnes 1 et 3, donne les lignes uniques de fichier 2
$ comm -13 colors_1.txt colors_2.txt
Black
Green
White
supprime les colonnes 2 et 3, donne les lignes uniques de fichier 1
$ comm -23 colors_1.txt colors_2.txt
Brown
Purple
Teal
Yellow

5-4. cmp

compare deux fichiers octet par octet.

Pratique pour comparer des fichiers binaires. Si les deux fichiers sont identiques, aucune sortie n’est effectuée (exit avec le statut 0). S’il y a des différences, la commande affiche la première différence, le numéro de ligne et la position de l’octet (exit statut 1). L’option -S permet de supprimer la sortie, pratique pour les scripts.

 
Sélectionnez
$ cmp /bin/grep /bin/fgrep
/bin/grep /bin/fgrep differ: byte 25, line 1
  • Plus d’exemples ici.

5-5. diff

compare des fichiers ligne par ligne.

Utile pour comparer une ancienne et une nouvelle version de fichier texte. Toutes les différences sont affichées, ce qui peut être indésirable si les fichiers sont très longs.

Options :

  • -s transmet un message quand les deux fichiers sont identiques ;
  • -y sortie en deux colonnes ;
  • -i ignore la casse lors de la comparaison ;
  • -w ignore les espaces blancs ;
  • -r comparaison récursive entre deux dossiers spécifiés ;
  • -q indique seulement si les fichiers diffèrent.

Exemples :

  • diff -s test_list_mar2.txt test_list_mar3.txt compare les deux fichiers ;
  • diff -s report.log bkp/mar10/ pas besoin de spécifier le second fichier si leurs noms sont identiques ;
  • diff -qr report/ bkp/mar10/report/ compare récursivement les fichiers entre les dossiers « report » et « bkp/mar10/report », les fichiers ne correspondant pas sont également spécifiés sur la sortie ;

    • voir ce lien pour une analyse détaillée.
  • diff report/ bkp/mar10/report/ | grep -w '^diff' astuce utile pour obtenir uniquement les noms de fichiers ne correspondant pas (à condition qu’aucune non-correspondance ne contienne le mot entier « diff » en début de ligne).

Lecture supplémentaire

5-6. tr

Convertit ou élimine des caractères.

Options :

  • -d supprime des caractères spécifiques ;
  • -c ensemble des caractères devant être remplacés.

Exemples :

  • tr a-z A-Z < test_list.txt convertit les minuscules en majuscules ;
  • tr -d ._ < test_list.txt supprime les caractères point et underscore ;
  • tr a-z n-za-m < test_list.txt > encrypted_test_list.txt crypte l’entrée en remplaçant chaque caractère minuscule avec le 13e caractère suivant de l’alphabet.

    • Ce sera la même commande sur le fichier crypté pour effectuer le décryptage.
  • tr Q&A on unix stackexchange

5-7. sed

Éditeur de flux (stream editor) pour le filtrage et la transformation de texte.

Options :

  • -n supprime automatiquement l’affichage de l'espace de travail ;
  • -i éditer les fichiers sur place (fait une copie de sauvegarde si le SUFFIXE est fourni) ;
  • -r utilise les expressions/rationnelles régulières étendues ;
  • -e ajoute le script à exécuter à la commande ;
  • -f ajoute le contenu d’un fichier script contenant les commandes à exécuter.

    • Pour des exemples et des détails, se référer aux liens donnés ci-dessous.

Commandes :

Nous ne verrons des exemples que pour trois commandes utilisées.

  • d efface l'espace de travail et passe à la ligne suivante ;
  • p affiche l'espace de travail ;
  • s cherche et remplace ;
  • consultez les sections « les commandes souvent utilisées » et « les commandes les moins utilisées » dans info sed pour une liste complète des commandes.

intervalle

Par défaut, sed agit sur tout le contenu de l’entrée. Cela peut être affiné à un numéro de ligne spécifique ou à une rangée définie par des numéros de ligne, un motif de recherche, ou un mélange des deux.

  • n,m intervalle entre la ligne numéro n et la ligne numéro m, n et m inclus;
  • i~j agit entre i+j, i+2j, i+3j, etc. ;

    • 1~2 signifie la 1re, 3e, 5e, 7e ligne, etc. c’est-à-dire les lignes impaires ;
    • 5~3 signifie 5e, 8e, 11e, etc.
  • n seulement la ligne n ;
  • $ seulement la dernière ligne ;
  • /motif/ seulement les lignes correspondant au motif ;
  • n,/motif/ de la ligne n à la ligne correspondant au motif ;
  • n,+x de la ligne n à n+x ;
  • /motif/,m de la ligne correspondant au motif à la ligne m ;
  • /motif/,+x de la ligne correspondant au motif à cette ligne +x ;
  • /motif1/,/motif2/ de la ligne correspondant au motif 1 à la ligne correspondant au motif 2 ;
  • /motif/I de la ligne correspondant au motif, le motif ne sera pas sensible à la casse ;
  • pour plus de détails, voir la section « Sélectionner des lignes avec sed » dans info sed
  • voir les expressions régulières de la commande grep pour plus d’informations ;
  • voir aussi la section « vue d’ensemble de la syntaxe ds expressions régulières »dans info sed.

Exemples de suppression sélective :

  • sed '/cat/d' story.txt supprime chaque ligne contenant cat ;
  • sed '/cat/!d' story.txt supprime chaque ligne ne contenant pas cat ;
  • sed '$d' story.txt supprime la dernière ligne du fichier ;
  • sed '2,5d' story.txt supprime les lignes 2,3,4,5 du fichier ;
  • sed '1,/test/d' dir_list.txt supprime toutes les lignes du début de fichier à la première occurrence de la ligne contenant test (la ligne correspondant est également supprimée) ;
  • sed '/test/,$d' dir_list.txt supprime toutes les lignes de la ligne contenant test à la fin de fichier.

Exemples d’affichage sélectif :

  • sed -n '5p' story.txt affiche la cinquième ligne, l’option -n annule le comportement par défaut de sed ;

  • sed -n '/cat/p' story.txt affiche chaque ligne contenant le texte cat ;

    • équivalent à sed '/cat/!d' story.txt.
  • sed -n '4,8!p' story.txt affiche toutes les lignes sauf les lignes 4 à 8 ;
  • man grep | sed -n '/^\s*code de sortie/I,/^$/p' extrait du manuel l’information « exit status »d’une commande donnée (grep dans l’exemple) ;

    • /^\s*code de sortie/I vérifie qu’une ligne commande par « code de sortie » sans respecter la casse, des espaces blancs peuvent être présents en début de ligne ;
    • /^$/ ligne vide ;
  • man ls | sed -n '/^\s*-F/,/^$/p' extrait du manuel les informations d’option d’une commande (ls dans l’exemple) ;

    • /^\s*-F/ la ligne commençant par l’option –F, les espaces blancs peuvent être présents en début de ligne.

Exemples pour faire des recherches et remplacements :

  • sed -i 's/cat/dog/g' story.txt recherche chaque occurrence de « cat » et la remplace par « dog » dans story.txt ;
  • sed -i.bkp 's/cat/dog/g' story.txt en plus de l’édition du fichier, crée un fichier de sauvegarde « story.txt.bkp », donc si une erreur se produit, le fichier original peut être restauré ;

    • sed -i.bkp 's/cat/dog/g' *.txt pour effectuer l’opération sur tous les fichiers du dossier courant se terminant avec .txt ;
  • sed -i '5,10s/cat/dog/gI' story.txt recherche et remplace chaque occurrence de « cat » (non sensible à la casse à cause de l’option I) par « dog » dans story.txt seulement dans les lignes 5 à 10 ;
  • sed '/cat/ s/animal/mammifère/g' story.txt remplace animal par mammifère dans toutes les lignes contenant « cat » ;

    • Comme l’option -i n’est pas utilisée, la sortie est affichée sur la sortie standard et story.txt n’est pas modifié ;
    • les espaces entre les intervalles et les commandes sont optionnels, sed '/cat/s/animal/mammal/g' story.txt peut aussi être utilisé ;
  • sed -i -e 's/cat/dog/g' -e 's/lion/tiger/g' story.txt cherche et remplace chaque occurrence de « cat » par « dog » et « lion » par « tiger »

    • n’importe quel nombre d’options -e peut être utilisé,
    • sed -i 's/cat/dog/g ; s/lion/tiger/g' story.txt autre syntaxe possible, les espaces autour de ; sont optionnels ;
  • sed -r 's/(.*)/abc: \1 :xyz/' list.txt ajoute le préfixe « abc: »  et le suffixe « :xyz » à chaque ligne de list.txt ;
  • sed -i -r "s/(.*)/$(basename $PWD)\/\1/" dir_list.txt ajoute le nom du dossier courant et le caractère antislash en début de chaque ligne ;

    • Notez l'utilisation des guillemets doubles pour effectuer la substitution de commande.
  • sed -i -r "s|.*|$HOME/\0|" dir_list.txt ajoute le dossier et l'antislash à chaque début de ligne ;

    • Comme la valeur de « $HOME » contient elle-même l'antislash, nous ne pouvons pas utiliser / comme délimiteur ;
    • Tout caractère autre qu’un l'antislash ou retour chariot peut être utilisé comme délimiteur, par exemple | # ^ voir ce lien pour plus d'informations.
    • \0 référence arrière contient la chaîne correspondante entière.

Exemple de fichiers d’entrées :

 
Sélectionnez
$ cat mem_test.txt
mreg2 = 1200 # starting address
mreg4 = 2180 # ending address
dreg5 = get(mreg2) + get(mreg4)
print dreg5
  • remplace toutes les reg par register
 
Sélectionnez
$ sed 's/reg/register/g' mem_test.txt
mregister2 = 1200 # starting address
mregister4 = 2180 # ending address
dregister5 = get(mregister2) + get(mregister4)
print dregister5
  • change les adresses de départ et fin
 
Sélectionnez
$ sed 's/1200/1530/; s/2180/1870/' mem_test.txt 
mreg2 = 1530 # starting address
mreg4 = 1870 # ending address

dreg5 = get(mreg2) + get(mreg4)
print dreg5
$ # pour faire des changements seulement sur les initialisations mreg , utilisez
$ # sed '/mreg[0-9] *=/ {s/1200/1530/; s/2180/1870/}' mem_test.txt
  • Utilisation de variables bash
 
Sélectionnez
$ s_add='1760'; e_add='2500'
$ sed "s/1200/$s_add/; s/2180/$e_add/" mem_test.txt
mreg2 = 1760 # starting address
mreg4 = 2500 # ending address
dreg5 = get(mreg2) + get(mreg4)
print dreg5
  • Sépare le code des commentaires
 
Sélectionnez
$ sed -E 's/^([^#]+)(#.*)/\2\n\1/' mem_test.txt 
# starting address
mreg2 = 1200
# ending address
mreg4 = 2180
dreg5 = get(mreg2) + get(mreg4)
print dreg5
  • Intervalle de lignes correspondant à un motif
 
Sélectionnez
$ seq 20 | sed -n '/3/,/5/p'
3
4
5
13
14
15
  • Édition à la volée
 
Sélectionnez
$ sed -i -E 's/([md]r)eg/\1/g' mem_test.txt
$ cat mem_test.txt
mr2 = 1200 # starting address
mr4 = 2180 # ending address
dr5 = get(mr2) + get(mr4)
print dr5
$ # plus d'une fichier d'entrée peut être donné
$ # utiliser un motif glob si les fichiers partagent un point commun, ex-: *.txt

Lecture supplémentaire

5-8. awk

Langage de recherche de motif et de traitement de texte.

Le nom awk dérive du nom de ses auteurs Alfred Aho, Peter Weinberger et Brian Kernighan.

Syntaxe :

  • awk 'BEGIN {initialize} condition1 {stmts} condition2 {stmts}... END {finish}'

    • BEGIN {initialize} est utilisé pour initialiser des variables (peut être utilisé pour définir des variables utilisateur, des variables awk, ou les deux), exécuté une fois – bloc optionnel ;
    • condition1 {stmts} condition2 {stmts}... action effectuée sur chaque ligne d’entrée, condition est optionnel, plus d’un bloc {} peut être utilisé avec ou sans condition ;
    • END {finish} action à effectuer une fois en fin de programme – bloc optionnel ;
  • Les commandes peuvent être écrites dans un fichier et passé avec l’option -f plutôt que de les écrire sur la ligne de commande ;

    • pour des exemples et détails, referez-vous aux liens donnés ci-dessous.

Exemple d’entrées de fichier :

 
Sélectionnez
$ cat test.txt
abc  : 123 : xyz
3    : 32  : foo
-2.3 : bar : bar
  • affiche juste quelque chose, aucune entrée.
 
Sélectionnez
$ awk 'BEGIN{print "Hello!\nTesting awk one-liner"}'
Hello!
Testing awk one-liner
  • recherche et remplace.
  • Quand la portion {stmts} n’est pas spécifiée, par défaut {print $0} est exécuté si la condition est évaluée à true

    • 1 est généralement utilisé comme expression awk pour afficher le contenu de $0 après avoir effectué un traitement ;
    • la déclaration print sans argument va afficher le contenu de $0.
 
Sélectionnez
$ # sub va remplacer seulement la première occurrence
$ # le troisième argument de sub spécifie la variable à changer, par défaut $0
$ awk '{sub("3", "%")} 1' test.txt 
abc  : 12% : xyz
%    : 32  : foo
-2.% : bar : bar

$ # gsub va remplacer toutes les  occurrences
$ awk '{gsub("3", "%")} 1' test.txt 
abc  : 12% : xyz
%    : %2  : foo
-2.% : bar : bar

$ # ajoute une condition pour restreindre le traitement seulement à ces enregistrements
$ awk '/foo/{gsub("3", "%")} 1' test.txt 
abc  : 123 : xyz
%    : %2  : foo
-2.3 : bar : bar

$ # utilisation de variables shell 
$ r="@"
$ awk -v r_str="$r" '{sub("3", r_str)} 1' test.txt 
abc  : 12@ : xyz
@    : 32  : foo
-2.@ : bar : bar
$ # les variables d'environnement bash comme PWD, HOME sont aussi accessibles via ENVIRON
$ s="%" awk '{sub("3", ENVIRON["s"])} 1' test.txt
abc  : 12% : xyz
%    : 32  : foo
-2.% : bar : bar
  • filtrage de contenu
 
Sélectionnez
$ # motifs regex, par défaut testé contre $0
$ awk '/a/' test.txt 
abc  : 123 : xyz
-2.3 : bar : bar

$ # utiliser ! Pour inverser la condition
$ awk '!/abc/' test.txt 
3    : 32  : foo
-2.3 : bar : bar
$ seq 30 | awk 'END{print}'
30
$ # generique length(var) - $0 pare défaut
$ seq 8 13 | awk 'length==1'
8
9
  • Sélection basée sur les numéros de ligne
  • NR est le nombre d'enregistrements
 
Sélectionnez
$ seq 123 135 | awk 'NR==7'
129

$ seq 123 135 | awk 'NR>=3 && NR<=5'
125
126
127
$ seq 5 | awk 'NR>=3'
3
4
5
$ # pour des entrées importantes, utilisez exit pour éviter le traitement d'enregistrements inutiles
$ seq 14323 14563435 | awk 'NR==234{print; exit}'
14556
  • sélection basée sur le début et la fin d’une condition
  • pour les exemples suivants :

    • les nombres 1 à 20 comme entrée ;
    • le motif regex /4/ est la condition de départ ;
    • le motif regex /6/ est la condition de fin.
  • f est utilisé idiomatiquement pour représenter un drapeau variable.
 
Sélectionnez
$ # enregistrements entre les conditions de départ et de fin
$ seq 20 | awk '/4/{f=1; next} /6/{f=0} f'
5
15

$ # les enregistrements entre les conditions de départ et de fin incluent aussi ceux de la condition de départ
$ seq 20 | awk '/4/{f=1} /6/{f=0} f'
4
5
14
15

$ # les enregistrements entre les conditions de départ et de fin incluent aussi ceux de la condition de fin
$ seq 20 | awk '/4/{f=1; next} f; /6/{f=0}'
5
6
15
16
$ # les enregistrements de départ à fin
$ seq 20 | awk '/4/{f=1} f{print} /6/{f=0}'
4
5
6
14
15
16
$ # enregistrements excluant début et fin
$ seq 10 | awk '/4/{f=1} !f; /6/{f=0}'
1
2
3
7
8
9
10
  • manipulations de colonnes
  • par défaut, un ou plusieurs espaces/tabulations consécutifs sont considérés comme des séparateurs de champs
 
Sélectionnez
$ echo -e "1 3 4\na b c"
1 3 4
a b c

$ # seconde colonne
$ echo -e "1 3 4\na b c" | awk '{print $2}'
3
b

$ # dernière colonne
$ echo -e "1 3 4\na b c" | awk '{print $NF}'
4
c
$ # le caractère séparateur par défaut est un caractère espace simple
$ echo -e "1 3 4\na b c" | awk '{print $1, $3}'
1 4
a c
$ # condition pour un champ spécifique
$ echo -e "1 3 4\na b c" | awk '$2 ~ /[0-9]/'
1 3 4
  • spécifier un séparateur de champs d’entrée/sortie différent
  • peut être une chaîne seule ou une regex, des séparateurs multiples peuvent être spécifiés en utilisant | dans le motif regex.
 
Sélectionnez
$ awk -F' *: *' '$1 == "3"' test.txt 
3    : 32  : foo

$ awk -F' *: *' '{print $1 "," $2}' test.txt 
abc,123
3,32
-2.3,bar

$ awk -F' *: *' -v OFS="::" '{print $1, $2}' test.txt 
abc::123
3::32
-2.3::bar

$ awk -F: -v OFS="\t" '{print $1 OFS $2}' test.txt 
abc       123
3         32
-2.3      bar
  • traitement des doublons de lignes/champs
 
Sélectionnez
$ cat duplicates.txt 
abc 123 ijk
foo 567 xyz
abc 123 ijk
bar 090 pqr
tst 567 zzz

$ # toute la ligne
$ awk '!seen[$0]++' duplicates.txt 
abc 123 ijk
foo 567 xyz
bar 090 pqr
tst 567 zzz
$ # colonne  particulière
$ awk '!seen[$2]++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr

Lecture supplémentaire

5-9. perl

L’interpréteur de langage Perl 5.

Larry Wall a écrit Perl comme un langage de script à usage général, empruntant ses fonctionnalités au C, aux scripts shell, awk, sed, grep, cut, sort, etc.

Le tableau de référence est donné ci-dessous pour les constructions utilisées fréquemment en Perl.

Descriptions adaptées de perldoc - command switches

Option

Description

-e

Exécute du code perl.

-n

itération sur les fichiers d'entrée dans une boucle, les lignes ne sont PAS imprimées par défaut.

-p

itération sur les fichiers d'entrée dans une boucle, les lignes sont imprimées par défaut.

-l

La ligne d’entrée chomp $\ obtient la valeur de $/ si aucun argument n'est donné.

-a

Divise les lignes d’entrée au niveau des espaces, définit implicitement -n pour les versions Perl à partir de 5.20.0.

-F

Spécifie le motif de séparation des lignes d’entrée, définit implicitement -a et -n pour les versions Perl à partir de 5.20.0.

-i

Édite les fichiers directement, si une extension est fournie, une copie de sauvegarde est faite.

-0777

Traite le fichier entier comme une seule chaîne, non recommandé pour de gros fichiers d’entrée.

Descriptions adaptés depuis perldoc - Special Variables

Variable

Description

$_

L’entrée et motif de recherche par défaut

$.

Numéro de ligne courant

$/

Séparateur d’enregistrements entrée, nouvelle ligne par défaut

$\

Séparateur d’enregistrements de sortie, chaîne par défaut

@F

Contient les champs de chaque ligne lue, applicable avec les options -a ou -F.

%ENV

Contient les variables d'environnement courantes.

$ARGV

Contient le nom du fichier courant.

Fonction

Description

length

Retourne la longueur n caractères de la valeur de EXPR. Si EXPR est omis, retourne la longueur de $_

eof

Retourne 1 si la prochaine lecture sur FILEHANDLE retourne end of file (fin de fichier).

Programme Perl simple :

 
Sélectionnez
$ perl -e 'print "Hello!\nTesting Perl one-liner\n"'
Hello!
Testing Perl one-liner

Exemple de fichier d’entrée :

 
Sélectionnez
$ cat test.txt
abc  : 123 : xyz
3    : 32  : foo
-2.3 : bar : bar
  • recherche et remplace
 
Sélectionnez
$ perl -pe 's/3/%/' test.txt
abc  : 12% : xyz
%    : 32  : foo
-2.% : bar : bar

$ # utilise le drapeau g pour remplacer toutes les occurrences, pas seulement la première correspondance
$ perl -pe 's/3/%/g' test.txt
abc  : 12% : xyz
%    : %2  : foo
-2.% : bar : bar

$ # remplacement conditionnel
$ perl -pe 's/3/@/g if /foo/' test.txt 
abc  : 123 : xyz
@    : @2  : foo
-2.3 : bar : bar

$ # utilisation de variables shell 
$ r="@"
$ perl -pe "s/3/$r/" test.txt 
abc  : 12@ : xyz
@    : 32  : foo
-2.@ : bar : bar

$ # l'approche préférée est d'utiliser la variable ENV hash
$ export s="%"
$ perl -pe 's/3/$ENV{s}/' test.txt
abc  : 12% : xyz
%    : 32  : foo
-2.% : bar : bar
  • recherche et remplacement de caractères spéciaux

Les constructions \Q and q() sont utiles pour annuler les métacaractères de motifs.

 
Sélectionnez
$ echo '*.^[}' | perl -pe 's/*.^[}/abc/'
Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE .^[}/ at -e line 1.

$ echo '*.^[}' | perl -pe 's/\*\.\^\[}/abc/'
abc

$ echo '*.^[}' | perl -pe 's/\Q*.^[}/abc/'
abc
$ echo '*.^[}' | perl -pe 's/\Q*.^[}/\$abc\$/'
$abc$
$ echo '*.^[}' | perl -pe 's/\Q*.^[}/q($abc$)/e'
$abc$
  • Affiche les lignes sur une base de numéro de ligne ou d’un motif
 
Sélectionnez
$ perl -ne 'print if /a/' test.txt 
abc  : 123 : xyz
-2.3 : bar : bar

$ perl -ne 'print if !/abc/' test.txt 
3    : 32  : foo
-2.3 : bar : bar

$ seq 123 135 | perl -ne 'print if $. == 7'
129

$ seq 1 30 | perl -ne 'print if eof'
30
$ # Utiliser exit pour gagner du temps sur les gros fichiers d'entrée
$ seq 14323 14563435 | perl -ne 'if($. == 234){print; exit}'
14556
$ # length() peut aussi être utilisé à la place de length $_
$ seq 8 13 | perl -lne 'print if length $_ == 1'
8
9
  • Affiche un intervalle de ligne basé sur les numéros de ligne ou un motif
 
Sélectionnez
$ seq 123 135 | perl -ne 'print if $. >= 3 && $. <= 5'
125
126
127

$ # $. est la variable par défaut par rapport à l'utilisation de ..
$ seq 123 135 | perl -ne 'print if 3..5'
125
126
127

$ # on peut utiliser beaucoup d'autres solutions, eof paraît plus lisible
$ seq 5 | perl -ne 'print if 3..eof'
3
4
5

$ # la correspondance du motif spécifié par /motif/ est vérifiée par rapport à $_
$ seq 5 | perl -ne 'print if 3../4/'
3
4

$ seq 1 30 | perl -ne 'print if /4/../6/'
4
5
6
14
15
16
24
25
26

$ seq 2 8 | perl -ne 'print if !(/4/../6/)'
2
3
7
8

.. vs ...
$ echo -e '10\n11\n10' | perl -ne 'print if /10/../10/'
10
10
$ echo -e '10\n11\n10' | perl -ne 'print if /10/.../10/'
10
11
10
  • Manipulations de colonnes
 
Sélectionnez
$ echo -e "1 3 4\na b c" | perl -nale 'print $F[1]'
3
b

$ echo -e "1,3,4,8\na,b,c,d" | perl -F, -lane 'print $F[$#F]'
8
d

$ perl -F: -lane 'print "$F[0] $F[2]"' test.txt 
abc    xyz
3      foo
-2.3   bar

$ perl -F: -lane '$sum+=$F[1]; END{print $sum}' test.txt 
155

$ perl -F: -lane '$F[2] =~ s/\w(?=\w)/$&,/g; print join ":", @F' test.txt 
abc  : 123 : x,y,z
3    : 32  : f,o,o
-2.3 : bar : b,a,r

$ perl -F'/:\s*[a-z]+/i' -lane 'print $F[0]' test.txt 
abc  : 123 
3    : 32  
-2.3 

$ perl -F'\s*:\s*' -lane 'print join ",", grep {/[a-z]/i} @F' test.txt 
abc,xyz
foo
bar,bar
$ perl -F: -ane 'print if (grep {/\d/} @F) < 2' test.txt
abc  : 123 : xyz
-2.3 : bar : bar
  • Traiter les doublons :
 
Sélectionnez
$ cat duplicates.txt 
abc 123 ijk
foo 567 xyz
abc 123 ijk
bar 090 pqr
tst 567 zzz

$ # toute la ligne
$ perl -ne 'print if !$seen{$_}++' duplicates.txt 
abc 123 ijk
foo 567 xyz
bar 090 pqr
tst 567 zzz
$ # colonne  particulière
$ perl -ane 'print if !$seen{$F[1]}++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr
  • traitement mutiligne :
 
Sélectionnez
$ # sauvegarde les lignes précédentes pour faciliter les correspondances mutlilignes
$ perl -ne 'print if /3/ && $p =~ /abc/; $p = $_' test.txt 
3    : 32  : foo

$ perl -ne 'print "$p$_" if /3/ && $p =~ /abc/; $p = $_' test.txt 
abc  : 123 : xyz
3    : 32  : foo

$ # avec la correspondance multiligne, -0777 slurping not advisable for very large files
$ perl -0777 -ne 'print $1 if /.*abc.*\n(.*3.*\n)/' test.txt 
3    : 32  : foo
$ perl -0777 -ne 'print $1 if /(.*abc.*\n.*3.*\n)/' test.txt 
abc  : 123 : xyz
3    : 32  : foo

$ # uttiliser le drapeau s pour permettre la correspondance .*  à travers les lignes
$ perl -0777 -pe 's/(.*abc.*32)/ABC/s' test.txt 
ABC  : foo
-2.3 : bar : bar

$ # utiliser le drapeau m si l'ancre ^$ est requise pour faire correspondre les lignes individuelles
$ perl -0777 -pe 's/(.*abc.*3)/ABC/s' test.txt 
ABC : bar : bar
$ perl -0777 -pe 's/(.*abc.*^3)/ABC/sm' test.txt 
ABC    : 32  : foo
-2.3 : bar : bar
$ # affiche plusieurs lignes après la ligne correspondant
$ perl -ne 'if(/abc/){ print; foreach (1..2){$n = <>; print $n} }' test.txt
abc  : 123 : xyz
3    : 32  : foo
-2.3 : bar : bar
  • Utilisation de modules :
 
Sélectionnez
$ echo 'a,b,a,c,d,1,d,c,2,3,1,b' | perl -MList::MoreUtils=uniq -F, -lane 'print join ",",uniq(@F)'
a,b,c,d,1,2,3

$ base64 test.txt 
YWJjICA6IDEyMyA6IHh5egozICAgIDogMzIgIDogZm9vCi0yLjMgOiBiYXIgOiBiYXIK
$ base64 test.txt | base64 -d
abc  : 123 : xyz
3    : 32  : foo
-2.3 : bar : bar
$ base64 test.txt | perl -MMIME::Base64 -ne 'print decode_base64($_)' 
abc  : 123 : xyz
3    : 32  : foo
-2.3 : bar : bar
$ perl -MList::MoreUtils=indexes -nale '@i = indexes { /[a-z]/i } @F if $. == 1; print join ",", @F[@i]' test.txt
abc,xyz
3,foo
-2.3,bar
  • Édition à la volée :
 
Sélectionnez
$ perl -i -pe 's/\d/*/g' test.txt 
$ cat test.txt 
abc  : *** : xyz
*    : **  : foo
-*.* : bar : bar

$ perl -i.bak -pe 's/\*/^/g' test.txt 
$ cat test.txt
abc  : ^^^ : xyz
^    : ^^  : foo
-^.^ : bar : bar
$ cat test.txt.bak
abc  : *** : xyz
*    : **  : foo
-*.* : bar : bar

Lecture supplémentaire

5-10. cut

Retire des sections de chaque ligne de fichier.

Pour les opérations sur des colonnes bien délimitables, la commande cut est pratique.

Exemples :

  • ls -l | cut -d' ' -f1 première colonne de ls -l :

    • l’option-d spécifie le caractère délimiteur, dans ce cas, c’est un caractère espace seul (le délimiteur par défaut est le caractère TAB).
    • l’option-f spécifie que champ affiché séparé par des virgules, dans ce cas, le champ 1.
  • cut -d':' -f1 /,etc./passwd affiche la première colonne du fichier /,etc/passwd.
  • cut -d':' -f1,7 /,etc./passwd affiche la 1re et la 7e colonne du fichier /,etc/passwd file avec caractère séparateur « : ».
  • cut -d':' --output-delimiter=' ' -f1,7 /,etc/passwd utilise l’espace comme délimiteur entre la 1re te 7e colonne durant l’affichage.
  • cut Q&A on unix stackexchange

5-11. paste

Fusionne les lignes d’un fichier/

Exemples :

  • paste list1.txt list2.txt list3.txt > combined_list.txt combine les trois fichiers par colonne en un seul fichier. Les entrées sont séparées par le caractère TAB.
  • paste -d':' list1.txt list2.txt list3.txt > combined_list.txt les entrées sont séparées par le caractère « : » au lieu de TAB.

    • Voir la commande pr pour plusieurs caractères de délimitation
  • paste Q&A on unix stackexchange
 
Sélectionnez
$ # joindre plusieurs fichiers
$ paste -d, <(seq 5) <(seq 6 10)
1,6
2,7
3,8
4,9
5,10
$ paste -d, <(seq 3) <(seq 4 6) <(seq 7 10)
1,4,7
2,5,8
3,6,9
,,10
  • colonne simple vers colonnes multiples :
 
Sélectionnez
$ seq 5 | paste - -
1    2
3    4
5
$ # spécifier plusieurs délimiteurs de sortie, tab par défaut
$ seq 5 | paste -d, - -
1,2
3,4
5,
$ # si le nombre de colonnes à spécifier est important, utilisez l'astuce printf
$ seq 5 | paste $(printf -- "- %.s" {1..3})
1    2    3
4    5
  • Combine toutes les lignes en une seule :
 
Sélectionnez
$ seq 10 | paste -sd,
1,2,3,4,5,6,7,8,9,10
$ # pour plusieurs caractères de délimitation, perl peut être utilisé
$ seq 10 | perl -pe 's/\n/ : / if(!eof)'
1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10

5-12. column

Listes colinéaires :

 
Sélectionnez
$ cat dishes.txt 
North alootikki baati khichdi makkiroti poha 
South appam bisibelebath dosa koottu sevai 
West dhokla khakhra modak shiro vadapav 
East handoguri litti momo rosgulla shondesh
$ column -t dishes.txt
North  alootikki  baati         khichdi  makkiroti  poha
South  appam      bisibelebath  dosa     koottu     sevai
West   dhokla     khakhra       modak    shiro      vadapav
East   handoguri  litti         momo     rosgulla   shondesh
  • Plus d’exemples ici.

5-13. pr

Convertit des fichiers texte pour l’affichage.

 
Sélectionnez
$ pr sample.txt
2016-05-29 11:00                    sample.txt                    Page 1
…
…
…
  • Les options incluent la conversion de textes pour l’affichage/l’impression avec en-tête, pied de page , ombres de page, double-espace un fichier, combinaison de plusieurs colonnes, etc.
  • Plus d’exemples ici.
 
Sélectionnez
$ # colonne simple vers plusieurs colonnes, séparées verticalement
$ # par exemple, dans la commande ci-dessous, la sortie de seq est découpée en deux
$ seq 5 | pr -2t
1                    4
2                    5
3
$ # différents délimiteurs de sortie peuvent être utilisés en utilisant le paramètre -s
$ seq 5 | pr -2ts' '
1 4
2 5
3
$ seq 15 | pr -5ts,
1,4,7,10,13
2,5,8,11,14
3,6,9,12,15
  • Utiliser l’option -a pour afficher les colonnes horizontalement ou lieu de verticalement.
 
Sélectionnez
$ seq 5 | pr -2ats' : '
1 : 2
3 : 4
5

$ seq 15 | pr -5ats,
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
$ # utilise le caractère d'expansion $ dénoté par les caractères échappement comme  \t pour la tabulation
$ seq 5 | pr -3ts$'\t'
1    3    5
2    4
$ # ou laissez l'argument pour s vide, car la tabulation est le caractère par défaut
$ seq 5 | pr -3ts
1    3    5
2    4
  • La largeur de page par défaut est 72.
  • La formule (col-1)*longueur(délimiteur) + col semble fonctionner pour déterminer la largeur minimale requise pour un affichage de plusieurs colonnes.
  • L’option -J aidera à désactiver la rupture de ligne.
 
Sélectionnez
$ seq 74 | pr -36ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72
73,74
$ seq 74 | pr -37ats,
pr: page width too narrow
$ # (37-1)*1 + 37 = 73
$ seq 74 | pr -Jw 73 -37ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37
38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74
$ # (3-1)*4 + 3 = 11
$ seq 6 | pr -Jw 10 -3ats'::::'
pr: page width too narrow
$ seq 6 | pr -Jw 11 -3ats'::::'
1::::2::::3
4::::5::::6
  • Utilisez l'option -m option pour combiner plusieurs fichiers en parallèle
 
Sélectionnez
$ pr -mts', ' <(seq 3) <(seq 4 6) <(seq 7 9)
1, 4, 7
2, 5, 8
3, 6, 9

Nous pouvons utiliser une combinaison de différentes commandes pour des opérations compliquées, par exemple, une transposition de table.

 
Sélectionnez
$ tr ' ' '\n' < dishes.txt | pr -$(wc -l < dishes.txt)t
North               South               West                East
alootikki           appam               dhokla              handoguri
baati               bisibelebath        khakhra             litti
khichdi             dosa                modak               momo
makkiroti           koottu              shiro               rosgulla
poha                sevai               vadapav             shondesh

Notez comment pr organise proprement les colonnes. Si les espaces sont trop importants, nous pouvons utiliser column.

 
Sélectionnez
$ tr ' ' '\n' < dishes.txt | pr -$(wc -l < dishes.txt)ts | column -t
North      South         West     East
alootikki  appam         dhokla   handoguri
baati      bisibelebath  khakhra  litti
khichdi    dosa          modak    momo
makkiroti  koottu        shiro    rosgulla
poha       sevai         vadapav  shondesh

6. Shell

6-1. Qu'est-ce que le Shell ?

Citation de Wikipedia :

Un shell Unix est un interpréteur de commandes destiné aux systèmes d'exploitation Unix et de type Unix qui permet d'accéder aux fonctionnalités internes du système d'exploitation. Il se présente sous la forme d'une interface en ligne de commande accessible depuis la console ou un terminal. L'utilisateur lance des commandes sous forme d'une entrée texte exécutée ensuite par le shell. Dans les différents systèmes d'exploitation Microsoft Windows, le programme analogue est command.com, ou cmd.exe.

Les systèmes d'exploitation de type Unix disposent le plus souvent d'un shell. À l'origine, l'interpréteur de commandes par défaut était sh, qui donna naissance à de nombreuses variantes, dont csh, étendu en tcsh, ou ksh, ou encore rc... Mais aujourd'hui bash, s'inspirant de sh, ksh, et csh, est le shell le plus répandu, bien qu'il existe d'autres interpréteurs de commandes, comme zsh, ou ash.

  • Interprète les commandes utilisateur ;

    • depuis le terminal, depuis un fichier ou un script shell,
    • développe les jokers (comme « * »), les substitutions de commandes/variables.
  • Historique de commandes, complétion de commandes, et édition de commandes.
  • Gère les processus.
  • Variables Shell pour personnaliser l’environnement.
  • Différence entre le shell, tty et la console

6-2. Shells populaires

Comme tout logiciel indispensable, les shells ont subi des transformations depuis les jours du basique sh qui était utilisé dans les Unix des années 70. Alors que bash est par défaut dans la plupart des distributions communes, des shells riches et puissants sont encore développés et fournis.

  • sh bourne shell (les distributions légères peuvent être fournies avec le shell sh ; seulement) ;
  • bash bourne again shell ;
  • csh C shell ;
  • tcsh tenex C shell ;
  • ksh Korn shell ;
  • zsh Z shell (bourne shell avec améliorations incluant des fonctionnalités de bash, tcsh, ksh)
  • cat /,etc./shells affiche la liste des shells de login disponibles dans la distribution courante ;
  • echo $SHELL chemin du shell de l’utilisateur courant.

Lecture supplémentaire

6-3. Jokers

Il est facile de spécifier complètement le nom des fichiers en arguments de commande quand il y en a un petit nombre. Mais supposons que nous devions supprimer des centaines de fichiers de log, répartis dans différents sous-dossiers ! Le jokers, aussi connus en tant que motif de globbing nous aident dans ce cas précis, à condition que les noms des fichiers aient un point commun à exploiter. Nous avons déjà vu les expressions régulières utilisées dans les commandes comme grep et sed. Les jokers du shell sont similaires, mais il y a des différences syntaxiques et fondamentales.

  • * correspond à tout caractère, 0 ou plusieurs fois ;

    • cas particulier : * ne fera pas de correspondance pour les noms des fichiers commençant par . Et doivent être spécifiés ;
  • ? correspond à tout caractère 1 fois ;
  • [aeiou] correspond à n’importe quelle voyelle ;
  • [!aeiou] exclut toute voyelle, çà correspond aux consonnes ;
  • [!0-9] correspond à tout caractère sauf les chiffres ;
  • [a-z] correspond aux caractères minuscules de a à z ;
  • [0-9a-fA-F] correspond à tout caractère hexadécimal ;
  • {word1,word2} correspond à un des mots spécifiés.

    • Les mots peuvent être eux-mêmes avec des jokers.

Exemples :

  • ls txt* liste tous les fichiers commençant par txt ;
  • ls *txt* liste tous les fichiers contenant txt n’importe où dans leur nom ;
  • ls *txt liste tous les fichiers finissant avec txt dans le dossier courant ;
  • ls -d .* liste seulement les fichiers cachés ;
  • rm *.??? supprime tout fichier avec une extension de trois caractères ;
  • ls bkp/201[0-5] liste les fichiers du dossier bkp correspondant à 2010/2011/2012/2013/2014/2015 ;
  • echo *txt utilise la commande echo pour voir comment les jokers se développent.

Développement d’accolades :

  • ls *{txt,log} liste tous les fichiers finissant par txt ou log dans le dossier courant ;
  • cp ~/projects/adders/verilog/{half_,full_}adder.v . copie half_adder.v et full_adder.v dans le dossier courant ;
  • mv story.txt{,.bkp} renomme story.txt en story.txt.bkp ;
  • cp story.txt{,.bkp} pour créer un fichier bkp en conservant l’original ;
  • mv story.txt{.bkp,} renomme story.txt.bkp en story.txt ;
  • mv story{,_old}.txt renomme story.txt en story_old.txt
  • touch file{1..4}.txt comme touch file1.txt file2.txt file3.txt file4.txt ;
  • touch file_{x..z}.txt comme touch file_x.txt file_y.txt file_z.txt ;
  • rm file{1..4}.txt comme rm file1.txt file2.txt file3.txt file4.txt ;
  • echo story.txt{,.bkp} affiche la version développée « story.txt story.txt.bkp » , utilisé pour tester avant exécution.

Globs étendus :

Depuis info bash, ou pattern-list est une liste d’un ou plusieurs motifs séparés par un |.

  • ?(pattern-list) correspond à 0 ou une occurrence du motif donné ;
  • *(pattern-list) correspond à 0 ou une occurrence du motif donné ;
  • +(pattern-list) correspond à 1 ou une occurrence du motif donné ;
  • @(pattern-list) correspond à 1 occurrence du motif donné ;
  • !(pattern-list) correspond à tout sauf un des motifs donnés.

Pour tester si extglob est actif ou pour activer/désactiver :

 
Sélectionnez
$ shopt extglob 
extglob            on

$ # unset extglob
$ shopt -u extglob 
$ shopt extglob 
extglob            off

$ # set extglob
$ shopt -s extglob
$ shopt extglob
extglob            on

Exemples

 
Sélectionnez
$ ls
123.txt  main.c  math.h  power.log

$ echo +([0-9]).txt
123.txt
$ ls @(*.c|*.h)
main.c  math.h
$ ls !(*.txt)
main.c  math.h  power.log
$ ls !(*.c|*.h)
123.txt  power.log

Recherche récursive dans le dossier en cours et ses sous-dossiers :

 
Sélectionnez
$ find -name '*.txt'
./song_list.txt
./bar/f1.txt
./bar/baz/f2.txt
$ shopt -s globstar
$ ls **/*.txt
bar/baz/f2.txt  bar/f1.txt  song_list.txt

Lecture supplémentaire

6-4. Redirection

Par défaut, tous les résultats de commande sont affichés sur le terminal, qui est la destination par défaut de la sortie standard. Mais souvent, on pourrait vouloir sauver ou supprimer celle-ci , ou l‘envoyer comme entrée à une autre commande. De façon similaire, les entrées d’une commande peuvent être données depuis des fichiers ou d’autres commandes. Les erreurs sont des sorties spéciales générées lors d’un mauvais usage de commande ou de nom de commande.

  • < ou 0< est le gestionnaire de fichiers stdin ;
  • > or 1> est le gestionnaire de fichier stdout ;
  • 2> est le gestionnaire de fichier stderr ;

Redirection de sortie d’une commande vers un fichier :

  • grep -i 'error' report/*.log > error.log crée un nouveau fichier, l’écrase s’il existe déjà ;
  • grep -i 'fail' test_results_20mar2015.log >> all_fail_tests.log crée un nouveau fichier s’il n’existe pas, sinon ajoute le résultat au fichier ;
  • ./script.sh > /dev/null redirige la sortie vers un fichier spécial /dev/null qui va juste détruire ce qui est écrit dessus, quelle que soit la taille ;
  • Évitement explicite de l'option noclobber par l'opérateur de redirection >| . noclobber = pas d'écrasement de fichier existant.

Redirection de sortie d’une commande vers une autre commande :

  • ls -q | wc -l l’opérateur de « pipe » redirige stdout de ls vers stdin de la commande wc ;
  • du -sh * | sort -h calcule la taille des fichiers/dossiers, affiche la taille triée en mode humainement lisible ;
  • ./script.sh | tee output.log la commande tee affiche les commandes affichées sur la sortie standard aussi bien que dans un fichier.

Combiner la sortie de plusieurs commandes :

  • (head -5 ~/.vimrc ; tail -5 ~/.vimrc) > vimrc_snippet.txt plusieurs commandes peuvent être groupées dans des parenthèses et redirigées comme une seule sortie de commande ;

    • les commandes groupées entre parenthèses sont exécutées dans un sous-environnement shell.
  • { head -5 ~/.vimrc ; tail -5 ~/.vimrc ; } > vimrc_snippet.txt sera exécuté dans le contexte courant du shell.
  • Groupement de commandes.

Substitution de commande :

  • sed -i "s|^|$(basename $PWD)/|" dir_list.txt ajoute le chemin du dossier courant et un caractère antislash en début de chaque ligne ;

    • Notez l’usage des guillemets pour effectuer une substitution de commande.
  • file_count=$(ls -q | wc -l) sauve la sortie de commande dans une variable ;
  • Substitution de commande.

Substitution de processus :


Redirection d’erreur :

  • xyz 2> cmderror.log en supposant la non-existence de la commande xyz, Cela devrait donner une erreur redirigée dans le fichier spécifié ;
  • ./script.sh 2> /dev/null supprime les messages d’erreur.

Combiner stdout et stderr :

En supposant que le fichier « report.log » existe et contienne le texte « test » et pas de fichier « xyz.txt ».

Bash version supérieure à 4 :

  • grep 'test' report.log xyz.txt &> cmb_out.txt redirige stdout et stderr ensemble vers un fichier ;
  • grep 'test' report.log xyz.txt &>> cmb_out.txt ajoute stdout et stderr ensemble vers un fichier ;
  • ls report.log xyz.txt |& grep '[st]' redirige stdout et stderr vers stdin.

versions précédentes :

  • grep 'test' report.log xyz.txt > cmb_out.txt 2>&1 redirige stdout et stderr ensemble vers un fichier ;
  • grep 'test' report.log xyz.txt 2> cmb_out.txt 1>&2 redirige stdout et stderr ensemble vers un fichier ;
  • grep 'test' report.log xyz.txt >> cmb_out.txt 2>&1 ajoute stdout et stderr ensemble vers un fichier ;
  • ls report.log xyz.txt 2>&1 | grep '[st]' redirige stdout et stderr vers stdin.

Redirection d’entrée :

  • tr a-z A-Z < test_list.txt convertit les minuscules en majuscules, la commande tr lit seulement sur stdin et n’a pas la capacité de lire directement d’un fichier ;
  • wc -l < report.log utile pour éviter le nom de fichier dans la sortie de wc ;
  • < report.log grep 'test' utilise pour facilement modifier des commandes précédentes pour différentes options, motif de recherche, etc.
  • grep 'test' report.log | diff - test_list.txt la sortie de grep en tant qu’une des entrées de fichier pour la commande diff ;
  • différence entre << , <<< et < <

Utilisation de xargs pour rediriger la sortie d’une commande vers l’entrée d’une autre

  • grep -rlZ 'motif' | xargs -0 sed -i 's/motif/replace/' recherche et remplace seulement les fichiers correspondant au motif de recherche (Note : le motif de recherche pourrait être différent pour grep et sed selon l’exigence)

    • l’option -Z option serait d'imprimer le nom de fichier séparé par un caractère ASCII NULL qui serait à son tour compris par xargs via l’option -0. Cela assure que la commande ne cassera pas les noms de fichier contenant des caractères comme des espaces, retour chariot, etc.
  • Quand utiliser xargs

Lecture supplémentaire

6-5. Contrôle de processus

  • Un process ou processus est n’importe quel programme fonctionnant ;

    • un programme est un ensemble d’instructions écrites pour exécuter une tâche.
  • Un démon c’est un processus en tâche de fond ;
  • un Job en termes de Shell, est un processus qui n’est pas un démon, c’est-à-dire : un processus interactif avec contrôle de l’utilisateur.

ps :

affiche un instantané des processus courant :

kill :

Envoie un signal à un processus.

top :

affiche les processus Linux.

  • Presser M (majuscule) pour trier les processus par usage mémoire ;
  • Presser q pour quitter la commande ;
  • Presser W (majuscule) pour écrire votre vue préférée pour la commande top dans le fichier ~/.toprc et quitter immédiatement, donc au prochain appel de la commande, elle s’affichera avec le format que vous appréciez ;
  • htop est une solution plus agréable que top ;

    • instructions d'installation ici
  • top Q&A on unix stackexchange

free :

Affiche la taille de la mémoire libre et utilisée dans le système.

  • free -h affiche la mémoire système libre et occupée de façon humainement lisible.

Pgrep :

Recherche ou envoie un signal à des processus suivant leur nom et d’autres attributs.

  • pgrep -l foobar recherche les processus dont le nom contient foobar. Affiche le PID et le nom complet ;
  • pgrep -x gvim recherche les processus contenant exactement gvim dans leur nom ;
  • pgrep -c chrom nombre total des processus correspondant à chrom ;
  • pgrep -nl chrom le plus récent processus démarré correspondant à chrom.

Lecture supplémentaire

6-6. Lancer des processus en arrière-plan

Souvent, des commandes ou des scripts peuvent prendre plus de quelques minutes à s’exécuter, mais l’utilisateur peut avoir besoin de continuer à utiliser le shell. Ouvrir un nouveau shell peut être contre-productif si les variables locales du shell sont également nécessaires. Le shell fournit l’opérateur & pour basculer l’exécution d’une commande (ou d’un script) en arrière-plan et redonner l’accès au prompt à l’utilisateur. Cependant, les sorties standards et les erreurs sont toujours affichées sur le terminal sauf redirections appropriées.

  • tkdiff result_v1.log result_v2.log & tkdiff, si installé, montre les différences entre deux fichiers dans une interface graphique. Si & n’est pas utilisé, le programme bloquera la console.

Placer le job courant en arrière-plan

Que faire si vous oubliez d’ajouter & et qu’utiliser kill sur le processus peut corrompre plein de choses ?

  • Ctrl+z suspend le job en cours ;
  • bg met en arrière-plan le processus récemment suspendu ;
  • utilisation du shell ;
  • fg replace en avant-plan le processus précédemment mis en arrière-plan ;
  • jobs commande interne, affiche le statut des jobs ;
  • nohup commande lance une commande immunisée contre les blocages, avec sortie vers/hors tty.
  • controle de job

7. Personnalisation du shell

7-1. Variables

Citation de article on BASH Environment & Shell Variables

Les variables fournissent un moyen simple pour partager des réglages de configuration entre de multiples applications et processus dans Linux, et sont principalement définies dans un fichier de démarrage ou de configuration du shell.

Elles sont par convention soit des variables shell, soit des variables d’environnement. Les deux sont définies en utilisant des lettres capitales. Elles aident les utilisateurs à distinguer les variables d’environnement des autres contextes.

les « variables d’environnement » ont été créées pour être utilisées dans le shell courant et seront héritées par tout shell ou processus engendré par celui-ci. Les variables d’environnement peuvent aussi être utilisées pour passer des informations dans un processus engendré par un shell.

Les « variables shell » sont exclusivement contenues dans le shell dans lequel elles ont été créées. Elles sont essentiellement utilisées pour garder des traces de données éphémères, comme le dossier en cours dans une session.

Quelques exemples de variables :

  • HOME le dossier home de l’utilisateur courant ; l’argument par défaut de la commande interne CD. La valeur de cette variable est aussi utilisée lors de l’extension du tilde (~) ;
  • SHELL Le chemin complet du shell est gardé dans cette variable d’environnement. Elle n’est pas affectée quand le shell démarre, bash lui affecte le chemin shell au login de l’utilisateur courant ;
  • PATH Le chemin de recherche des commandes. C’est une liste de dossiers séparés par des deux-points dans laquelle le shell recherche les commandes. Voici une valeur commune : /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
  • PWD et OLDPWD le chemin complet du dossier en cours et de l’ancien dossier en cours ;
  • HISTFILESIZE,HISTSIZE,HISTCONTROL,HISTFILE variables en rapport avec l’ historique des commandes ;
  • PS1 la valeur de ce paramètre est développée et utilisée comme chaîne de prompt primaire. La valeur par défaut est \s-\v\$
  • printenv commande pour afficher les noms et valeurs des variables d’environnement ;
  • set commande interne pour afficher les noms et valeurs des variables d’environnement quand utilisé sans option/argument ;
  • echo "$HOME" utiliser $ quand la valeur de la variable est requise.

Variables définies par l’utilisateur

L’utilisateur peut également définir des variables, pour un usage temporaire, pour un script shell, etc.

Utiliser les minuscules est préféré pour éviter un éventuel conflit avec des variables shell ou d’environnement.

 
Sélectionnez
$ #tableau de nombres binaires par ordre croissant
$ dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
$ echo "${dec2bin[2]}"
00000010
$ echo "${dec2bin[120]}"
01111000
$ echo "${dec2bin[255]}"
11111111

Lecture supplémentaire

7-2. Fichiers de configuration

En utilisant des alias, des fonctions, des variables shell, etc., on peut personnaliser le shell selon ses besoins.

Depuis la section « FILES » dans info bash

  • /,etc./profile le fichier d’initialisation à l’échelle du système, exécuté pour les shells de connexion ;
  • /etc/bash.bashrc le fichier de démarrage au niveau système pour les shells interactifs ;
  • /etc/bash.bash.logout le fichier de nettoyage exécuté à la déconnexion du shell ;
  • ~/.bash_profile le fichier d’initialisation personnel, exécuté au login shell ;
  • ~/.bashrc Le fichier individuel de démarrage de shell interactif ;
  • ~/.bash_logout le fichier individuel de nettoyage à la déconnexion ;
  • ~/.inputrc fichier d’initialisation individuelle pour l’utilisation de readline.

~/.bashrc

De la section « INVOCATION » dans info bash

Quand un shell interactif qui n’est pas un shell de login est démarré, bash lit et exécute les commandes de /etc/bash.bashrc et ~/.bashrc, si ces fichiers existent. Cela peut être inhibé en utilisant l’option –norc, l’option --rcfile va forcer bash à lire et exécuter les commandes depuis un fichier plutôt que depuis /etc/bash.bashrc ou ~/.bashrc.

  • shopt fixe et supprime les options shell

    • shopt -s autocd change le dossier en tapant juste le nom, sans avoir à taper explicitement la commande cd (-s active/désactive cette option) ;
    • shopt -u autocd supprime/désactive l’option autocd ;
    • shopt -s dotglob inclut aussi les fichiers avec . dans le développement des jokers ;
    • Commande interne shopt
  • set Fixe ou supprime les valeurs des options du shell et les paramètres de position ;

    • set -o emacs utilise le style d’interface d’emacs pour l’édition de lignes ;
    • set -o vi utilise le style d’interface de vi pour l’édition de lignes ;
    • set -o history active l’historique de commandes ;
    • set +o history désactive l’historique de commandes, utilisé pour désactiver temporairement l’enregistrement des commandes dans l’historique jusqu’à réactivation ;
    • set -o montre le statut courant d’options variées si elles sont on/off.
    • Fixer les commandes internes
  • alias

    • les alias et les fonctions sont généralement utilisés pour construire de nouvelles commandes ou invoquer des commandes avec des options préférées ;
    • source ~/.bash_aliases pour éviter l’encombrement du fichier .bashrc. Il est recommandé de les mettre dans un fichier séparé et d’utiliser la commande source pour les ajouter à bashrc.
  • historique

    • par défaut, l’historique des commandes est stocké dans ~/.bash_history, ceci peut être changé en utilisant la variable HISTFILE ;
    • HISTSIZE=5000 cette commande précise le nombre de commandes de l’historique de la session shell courante. Une valeur négative signifiera une taille illimitée ;
    • HISTFILESIZE=10000 cette variable précise le nombre de commandes stockées dans le fichier d’historique. Utiliser une valeur négative signifiera une taille illimitée ;
    • HISTCONTROL=ignorespace:erasedups ne sauvegarde pas les commandes commençant par un espace et supprime toute entrée précédente représentant un doublon ;
    • shopt -s histappend ajoute au fichier d’historique plutôt que de l’écraser.
    • using bash history efficiently
    • common history across sessions
  • Fixer le prompt en utilisant la variable PS1

    • PS1="$ " simple prompt « $ « '
    • PS1="\s-\v\$ " le prompt par défaut, ajoute le numéro de version bash, par ex. : 'bash-4.3$ '
    • PS1="\u@\h\\$ \[$(tput sgr0)\]" est un moyen de dire fixer le prompt «  nom_utilisateur@nom_hote » ;
    • Moyen simple pour générer PS1 – les exemples ci-dessus sont générés en utilisant ce site, ainsi que l’option d’ajouter de la couleur ;
  • What does the ~/.bashrc file do?
  • Les distributions comme Ubuntu sont fournies avec un fichier ~/.bashrc déjà créé avec des configurations utilisées comme bash_completion.
  • Exemple de bashrc

~/.inputrc

Les raccourcis clavier pour la ligne de commande (readline) sont personnalisés dans ce fichier Par défaut le style Emacs est actif et peut être changé en utilisant la commande set comme expliqué dans la section précédente.
Certains des raccourcis clavier par défaut sont présentés plus loin dans ce chapitre.

  • "\e[A": history-search-backward flèche haut pour afficher les précédentes commandes ;
  • "\e[B": history-search-forward flèche bas pour se déplacer plus bas dans la liste de l’historique ;
  • "\C-d": unix-filename-rubout Ctrl+d pour supprimer arrière depuis le curseur à la limite du nom de fichier ;
  • set echo-control-characters off désactive l’affichage sur l’écran des caractères de contrôle comme ^C (Ctrl+C) ;
  • set completion-ignore-case on ignore la casse pour la complétion par la touche tabulation ;
  • set show-all-if-ambiguous on combine l’appui simple et double de Tab en un seul appui Tab ;
  • Introduction simple à Readline
  • discussion on GNU Readline library Readline : bibliothèque permettant à l'utilisateur d'interagir avec la ligne de commande.
  • exemple d'nputrc

~/.bash_aliases

Avant de créer un alias ou une fonction, utilisez type nom_alias pour vérifier si une commande ou un alias n’existe pas déjà avec ce nom.

  • alias utilisé sans argument, montre tous les alias actuellement définis, triés par ordre alphabétique ;
  • alias c='clear' crée un alias avec juste la lettre C pour la commande clear ;

    • Notez qu’il ne doit pas y avoir d’espace autour de l’opérateur = ;
  • alias b1='cd ../' crée un alias b1 pour aller dans le dossier au-dessus du dossier actuel ;
  • alias app='cd /home/xyz/Android/xyz/app/src/main/java/com/xyz/xyzapp/' crée un alias pour le dossier à nom long cité. Particulièrement utile quand on travaille sur des projets très longs ;

    • et si les alias sont oubliés dans le temps, ils peuvent être retrouvés en ouvrant le fichier ~/.bash_aliases ou en utilisant la commande alias ;
  • alias oa='gvim ~/.bash_aliases' ouvre le fichier des alias avec votre éditeur favori ;
  • alias sa='source ~/.bash_aliases' pratique pour appliquer des changements à la session courante ;
  • alias ls='ls --color=auto' colorise la sortie pour distinguer les types de fichiers ;
  • alias l='ls -ltrh' mappe les options favorites, plus la sortie couleur comme précédemment définie sera substituée à ls ;
  • alias grep='grep --color=auto' colorise le nom des fichiers, les numéros de ligne, les motifs correspondant, etc. ;
  • alias s='du -sh * | sort -h' trie les fichiers/dossiers par taille et les affiche au format lisible par les humains ;
  • \ls passez outre l’alias et utilisez la commande originale en utilisant le préfixe \ ;
  • ch() { man $1 | sed -n "/^\s*$2/,/^$/p" ; } simple commande help (ch) pour obtenir l’information sur une option de commande ;

    • par exemple : ch ls -F , ch grep -o , etc. ;
    • ch() { whatis $1; man $1 | sed -n "/^\s*$2/,/^$/p" ; } affiche également la description de la commande ;
    • ch fait un meilleur job avec la capacité de gérer de multiples options, de multiples arguments, les commandes internes, etc. ;
    • explainshell fait encore mieux.
  • o() { gnome-open "$@" &> /dev/null ; } ouvre les fichiers avec leur application par défaut, supprime la sortie et les messages d’erreur ;

    • par exemple: o bashguide.pdf ;
    • $1 premier argument ;
    • $2 second ;
    • $@ tous les arguments.
  • Exemple de bash_aliases.

Lecture supplémentaire

7-3. Raccourcis Readline mode Emacs

  • Ctrl+c envoie le signal SIGINT, demandant au processus en cours de fonctionnement de se terminer ;

  • Ctrl+c peut aussi être utilisé pour annuler la commande actuellement tapée et donner un nouveau prompt vierge ;
  • Ctrl+z suspend le processus courant ;
  • Tab la touche de tabulation complète la commande (même les alias) ou un nom de fichier s’il est unique, la double tabulation donne la liste des possibilités si non unique ;

    • set show-all-if-ambiguous on combine le simple ou double appui de tabulation en un seul appui ;
  • Ctrl+r commande de recherche dans l’historique. Après avoir pressé cette séquence de touches, tapez les caractères que vous souhaitez recherche, puis pressez la touche Echap pour retourner au prompt de commande ou pressez Entrer pour exécuter celle-ci ;
  • Esc+b déplace le curseur en arrière d’un mot ;
  • Esc+f déplace le curseur en avant d’un mot ;
  • Esc+Backspace suppression arrière jusqu’à la limite d’un mot ;
  • Ctrl+a ou Home déplace le curseur au début du prompt ;
  • Ctrl+e ou End déplace le curseur en fin de ligne de la ligne de commande ;
  • Ctrl+l conserve ce qui est tapé dans l’invite de commande et efface l’écran du terminal ;
  • Ctrl+u supprime du début de ligne jusqu’au curseur ;
  • Ctrl+k supprime du curseur à la fin de la ligne ;
  • Ctrl+t intervertit les deux précédents caractères autour de la position ;

    • Par exemple : si vous avez tapé « sp » à la place de « ps », presser Ctrl+t quand le curseur est à droite de « sp » et le changera en ps.
  • Esc+t inverse les deux mots autour de la position ;
  • !$ dernier argument utilisé ;

    • par exemple : sf cat temp.txt était la dernière commande utilisée, rm !$ supprimera le fichier temp.txt ;
    • Esc+ va insérer le dernier argument utilisé, pratique quand vous avez besoin de modifier avant exécution. Et aussi plusieurs appuis permettent de traverser l'avant-dernière commande et ainsi de suite.
  • Click du bouton de scrolling de la souris surlignez le texte que vous voulez copier et pressez le bouton de scrolling de la souris, puis pressez le même bouton à l’endroit de destination pour coller le texte ;

    • pour désactiver le collage du bouton de scrolling de la souris, utilisez la commande xinput et récupérez le numéro correspondant à votre souris, disons qu’il s’agit de 11 :
    • xinput set-button-map 11 1 0 3 pour désactiver ;
    • xinput set-button-map 11 1 2 3 pour réactiver.

8. Scripts shell

8-1. Besoin de scripts

Note :

  • .sh est typiquement utilisé comme extension pour les scripts shell.
  • Les éléments présentés ici sont pour bash, version 4.3.11(1)-release

8-2. script Hello

 
Sélectionnez
#!/bin/bash
# Print greeting message
echo "Hello $USER"
# Print day of week
echo "Today is $(date -u +%A)"
# use single quotes for literal strings
echo 'Have a nice day'

La première ligne a deux parties :

  • /bin/bash est le chemin de bash,

    • type bash pour obtenir le chemin ;
  • #! appelé aussi shebang, indique au chargeur de programme d'utiliser l'interpréteur à utiliser (chemin indiqué après le shebang).

Commentaires

  • Les commentaires commencent par # ;
  • Les commentaires peuvent aussi être placés en fin de ligne ;

    • echo 'Hello' # commentaire de fin de code
  • Multiline comments

Guillemets simples vs guillemets doubles

  • Les guillemets simples préservent la valeur littérale de chaque caractère entre ceux-ci ;
  • Les guillemets doubles préservent la valeur littérale de chaque caractère entre ceux-ci, à l’exception de « $' » « ` », « \ », et, quand le développement de l’historique est activé : « ! »
  • Difference between single and double quotes

la commande interne echo

  • help -d echo écrit les arguments sur la sortie standard ;
  • Par défaut, echo ajoute un retour chariot et n’interprète pas l’antislash ;
  • -n n’ajoute pas de retour chariot ;
  • -e active l’interprétation des échappements antislash qui suivent ;
  • -E supprime explicitement l’interprétation des échappements antislash ;
  • echo Q&A on unix stackexchange
 
Sélectionnez
$ chmod +x hello_script.sh
$ ./hello_world.sh
Hello learnbyexample
Today is Wednesday
Have a nice day

8-3. Sourcer un script

 
Sélectionnez
$ help -d source
source - Execute commands from a file in the current shell.
  • Si le script doit être exécuté dans l’environnement du shell courant plutôt que dans un sous-shell, utilisez le . ou la commande source ;

    • Par exemple, après l’édition de ~/.bashrc on peut utiliser source ~/.bashrc pour que les changements soient effectifs immédiatement.
 
Sélectionnez
$ # contents of prev_cmd.sh
prev=$(fc -ln -2 | sed 's/^[ \t]*//;q')
echo "$prev"
  • Par exemple, pour accéder à l’historique du shell interactif courant depuis un script
 
Sélectionnez
$ printf 'hi there\n'
hi there
$ bash prev_cmd.sh
$ printf 'hi there\n'
hi there
$ source prev_cmd.sh
printf 'hi there\n'

8-4. Arguments de ligne de commande

 
Sélectionnez
#!/bin/bash
# Print line count of files given as command line argument
echo "No of lines in '$1' is $(wc -l < "$1")"
echo "No of lines in '$2' is $(wc -l < "$2")"
  • Les arguments de ligne de commande sont sauvegardés selon leur position en commençant avec $1 $2 $3 etc.
  • Si un argument particulier requiert une chaîne de plusieurs mots, entourez-les de guillemets ou utilisez la séquence d’échappement appropriée.
  • $0 contient le nom du script lui-même, pratique pour coder différents comportements basés sur le nom de script utilisé.
  • $@ tableau de tous les arguments passés au script.
  • $# nombre d’arguments passés au script.
  • Utilisez les guillemets doubles autour des variables quand vous passez les valeurs à une autre commande.

  • bash special parameters reference
 
Sélectionnez
$ ./command_line_arguments.sh hello_script.sh test\ file.txt
No of lines in 'hello_script.sh' is 9
No of lines in 'test file.txt' is 5

8-5. Variables et comparaisons

  • dir_path=/home/guest l’espace a une signification particulière en bash, et ne peut être utilisé autour de = ;
  • greeting='hello world' utilisez les guillemets simples pour les chaînes littérales ;
  • user_greeting="hello $USER" utilisez les guillemets doubles pour les substitutions ;
  • echo $user_greeting utilisez $ quand une valeur de variable est requise ;
  • no_of_lines=$(wc -l < "$filename") utilisez les guillemets doubles autour d’une s variable quand vous passez sa valeur à une autre commande ;
  • num=534 des nombres peuvent aussi être déclarés ;
  • (( num = 534 )), mais utiliser (( )) pour les nombres vous rendra la vie plus facile ;
  • (( num1 > num2 )) les comparaisons de nombres peuvent être rendues plus lisibles entre (( )) ;
  • [[ -e story.txt ]] teste si le fichier/dossier existe ;
  • [[ $str1 == $str2 ]] pour la comparaison de chaînes.

Lecture supplémentaire

8-6. Accepter les saisies des utilisateurs de manière interactive

 
Sélectionnez
#!/bin/bash
# Récupère l'entrée utilisateur
echo 'Bonjour, ce script retourne la somme de deux nombres'
read -p 'Entrez les deux nombres séparés par un espace : ' number1 number2
echo -e "\n$number1 + $number2 = $((number1 + number2))"
echo 'Merci pour l'utilisation de script, bonne journée :)'
  • help -d read lit une ligne depuis l’entrée standard et l’éclate en différents champs suivant le caractère de délimitation fourni ;
  • -a place les mots dans un tableau en commençant à l’index 0 ;
  • -p affiche la chaîne PROMPT sans retour chariot avant de tenter une lecture ;
  • -s n’affiche pas en écho la saisie venant du terminal ;
  • Plus d'exemples avec lecture et obtention d'entrées depuis stdin.
 
Sélectionnez
$ ./user_input.sh
Bonjour, ce script retourne la somme de deux nombres
Entrez les deux nombres séparés par un espace :  7 42
7 + 42 = 49
Merci pour l'utilisation de script, bonne journée :)

8-7. if then else

 
Sélectionnez
#!/bin/bash
if (( $# != 2 ))
then
    echo "Erreur!! Merci de spécifier deux noms de fichier"
    #La convention simple pour la valeur de sortie est '0' pour un succès et '1' pour une erreur
    exit 1
else
    # Utilisez ; pour combiner plusieurs commandes sur une même ligne
    # l'option -f contrôle l’existence du fichier, ! Fait une négation de la valeur
    # des espaces autour de  [[ et ]] sont nécessaires
    if [[ ! -f $1 ]] ; then
        echo "Erreur!! '$1' n'est pas un nom de fichier valide" ; exit 1
    else
        echo "Nombres de lignes dans '$1' : $(wc -l < "$1")"
    fi
    # Exécution  conditionnelle
    [[ ! -f $2 ]] && echo "Erreur!! '$2' n'est pas un nom de fichier valide" && exit 1
    echo "Nombre de lignes dans '$2' : $(wc -l < "$2")"
fi
  • lors de la gestion d’arguments fournis par l’utilisateur, il est toujours conseillé de vérifier la fiabilité des arguments. Un simple contrôle peut réduire des heures de débogage frustrant quand les choses vont mal ;
  • le code entre le bloc if [[ ! -f $1 ]] ; then est seulement prévu pour la démonstration, nous pourrions aussi bien avoir utilisé la gestion d’erreur de la commande wc si le fichier n’existe pas ;
  • la valeur exit par défaut est 0 , ne doit donc pas être explicitement écrite pour l’achèvement correct d’un script ;
  • utilisez elif si vous avez besoin de plus de conditions après if ;
  • L'opérateur && est utilisé pour exécuter une commande seulement lorsque la précédente s’est exécutée avec succès ;
  • Pour rediriger un message d’erreur vers stderr, utilisez "Erreur!! Merci de fournir deux noms de fichier" 1>&2, etc.
  • Control Operators && and ||
  • Plus d'exemples pour les blocs conditionnels if.
 
Sélectionnez
$ ./if_then_else.sh 
Erreur!! Merci de fournir deux noms de fichier
$ echo $?
1

$ ./if_then_else.sh hello_script.sh 
Erreur!! Merci de fournir deux noms de fichier
$ echo $?
1

$ ./if_then_else.sh hello_script.sh xyz.tzt
Nombre de lignes dans 'hello_script.sh' : 9
Erreur!! 'xyz.tzt' n'est pas un nom de fichier valide 
$ echo $?
1
$ ./if_then_else.sh hello_script.sh 'test file.txt'
Nombre de lignes dans 'hello_script.sh' : 9
Nombre de lignes dans 'test file.txt' : 5
$ echo $?
0

Combiner if avec le statut exit d’une commande exécutée

Parfois, on peut avoir besoin de savoir si une opération prévue d’une commande a réussi ou non, puis prendre des mesures en conséquence. Un statut de sortie de 0 est considéré comme une condition réussie lors de l’utilisation avec if. Quand l’option est disponible, utilisez-la pour supprimer la sortie stdout/stderr de la commande à utiliser, sinon une redirection peut être nécessaire pour éviter une sortie sur le terminal.

 
Sélectionnez
$ grep 'echo' hello_script.sh 
echo "Hello $USER"
echo "Today is $(date -u +%A)"
echo 'Have a nice day'

$ # n'écrit rien sur la sortie standard
$ grep -q 'echo' hello_script.sh
$ echo $?
0
$ grep -q 'echo' xyz.txt
grep: xyz.txt: No such file or directory
$ echo $?
2
$ # Suppression des messages d'erreur à propos de fichiers inexistants ou non lisibles
$ grep -qs 'echo' xyz.txt
$ echo $?
2

Exemple

 
Sélectionnez
#!/bin/bash
if grep -q 'echo' hello_script.sh ; then
    # fait quelque chose
    echo "chaîne trouvée"
else
    # fait autre chose
    echo "chaîne non trouvée"
fi

8-8. boucle for

 
Sélectionnez
#!/bin/bash

# s'assure qu'au moins un argument est fourni
(( $# == 0 )) && echo "Error!! Merci de fournir au moins un nom de fichier" && exit eu

file_count=0
total_lines=0
# À chaque itération, la variable file prend l'argument à la position suivante
for file in "$@"
do
    # laisse wc montrer ses messages d'erreur si le fichier n'existe pas
    # termine le script si le statut de sortie de la commande wc command exit n'est pas 0
    no_of_lines=$(wc -l < "$file") || exit 1
    echo "Nombre de lignes dans '$file' : $no_of_lines"
    ((file_count++))
    ((total_lines = total_lines + no_of_lines))
done
echo -e "\nNombre total de fichiers = $file_count"
echo "Nombre total de lignes = $total_lines"
  • Cette forme de boucle for est pratique si vous voulez seulement un élément d’un tableau, sans avoir à faire une itération sur toute la longueur du tableau.
  • Dans cet exemple, nous utilisons l’opérateur de contrôle || pour stopper le script si wc échoue c’est-à-dire a un statut exit autre que 0.
 
Sélectionnez
$ ./for_loop.sh 
Erreur!! Merci de fournir au moins un nom de fichier
$ echo $?
1

$ ./for_loop.sh hello_script.sh if_then_else.sh command_line_arguments.sh
Nombres de lignes dans 'hello_script.sh' : 9
Nombre de lignes dans 'if_then_else.sh' : 21
Nombres de lignes dans 'command_line_arguments.sh' : 5
Nombre total de fichiers = 3
Nombre total de lignes = 35
$ echo $?
0
$ ./for_loop.sh hello_script.sh xyz.tzt
No of lines in 'hello_script.sh' is 9
./for_loop.sh: line 14: xyz.tzt: No such file or directory
$ echo $?
1

boucle for basée sur un index

 
Sélectionnez
#!/bin/bash
# Print 0 to 4
for ((i = 0; i < 5; i++))
do
    echo $i
done

Itération sur un tableau défini et utilisé

 
Sélectionnez
$ files=('report.log' 'pass_list.txt')
$ for f in "${files[@]}"; do echo "$f"; done
report.log
pass_list.txt

Fichiers spécifiés par un modèle glob

Une méprise commune est d’utiliser la sortie de la commande ls qui est inutile et sujette à erreur. Les arguments peuvent être utilisés à la place,

 
Sélectionnez
$ ls
pass_list.txt  power.log  report.txt
$ for f in power.log *.txt; do echo "$f"; done
power.log
pass_list.txt
report.txt

8-9. boucle while

 
Sélectionnez
#!/bin/bash
# Print 5 to 1
(( i = 5 ))
while (( i != 0 ))
do
    echo $i
    ((i--))
done
  • Utilisez while quand vous avez besoin d’exécuter des commandes selon une condition spécifiée.
 
Sélectionnez
$ ./while_loop.sh
5
4
3
2
1

8-10. Lecture d’un fichier

Lecture ligne par ligne

 
Sélectionnez
#!/bin/bash
while IFS= read -r line; do
    # do something with each line
    echo "$line"
done < 'files.txt'
  • IFS est utilisé pour spécifier le séparateur de champ qui est un espace par défaut. IFS= va supprimer la valeur par défaut et éviter de supprimer les espaces de début et fin ;
  • l’option -r pour read va empêcher l’interprétation de l’échappement \ ;
  • La dernière ligne du fichier ne sera pas lue si elle n’est pas correctement terminée par un retour chariot.
 
Sélectionnez
$ cat files.txt
hello_script.sh
if_then_else.sh
$ ./while_read_file.sh
hello_script.sh
if_then_else.sh

Lecture d’une ligne en différents champs

  • Par défaut, le délimiteur est l’espace.
  • Spécifiez-en un différent en fixant IFS
 
Sélectionnez
$ cat read_file_field.sh
#!/bin/bash

while IFS=: read -r genre name; do
    echo -e "$genre\t:: $name"
done < 'books.txt'
$ cat books.txt 
fantasy:Harry Potter
sci-fi:The Martian
mystery:Sherlock Holmes
$ ./read_file_field.sh
fantasy :: Harry Potter
sci-fi  :: The Martian
mystery :: Sherlock Holmes

Lecture de x caractères en même temps

 
Sélectionnez
$ while read -n1 char; do echo "Le caractère lu est : $char"; done <<< "\word"
Le caractère lu est : w
Le caractère lu est : o
Le caractère lu est : r
Le caractère lu est : d
Le caractère lu est :
$ # si le retour chariot de fin n'est pas souhaité
$ while read -n1 char; do echo "Le caractère lu est : $char"; done < <(echo -n "hi")
Le caractère lu est : h
Le caractère lu est : i
$ while read -r -n2 chars; do echo "Le caractère lu est : $chars"; done <<< "\word"
Le caractère lu est : \w
Le caractère lu est : or
Le caractère lu est : d

8-11. Débogage

  • -x affiche les commandes et leurs arguments comme elles sont exécutées ;
  • -v option verbose (bavard), affiche les lignes d’entrée du shell telles qu’elles sont lues ;
  • set xv utilisez cette commande pour activer le débogage depuis le script lui-même.
 
Sélectionnez
$ bash -x hello_script.sh 
+ echo 'Hello learnbyexample'
Hello learnbyexample
++ date -u +%A
+ echo 'Today is Friday'
Today is Friday
+ echo 'Have a nice day'
Have a nice day
$ bash -xv hello_script.sh 
#!/bin/bash
# Print greeting message
echo "Hello $USER"
+ echo 'Hello learnbyexample'
Hello learnbyexample
# Print day of week
echo "Today is $(date -u +%A)"
date -u +%A
++ date -u +%A
+ echo 'Today is Friday'
Today is Friday
# use single quotes for literal strings
echo 'Have a nice day'
+ echo 'Have a nice day'
Have a nice day

8-12. Cas d’utilisation dans le monde réel

Avec autant de copier-coller de commandes et leurs sorties impliquées dans la création de ces chapitres, des erreurs se produiront. Donc, un script pour vérifier l’exactitude sera pratique. Examinez le fichier Markdown ci-dessous :

 
Sélectionnez
## <a name="some-heading"></a>Some heading

Some explanation

```bash
$ seq 3
1
2
3

$ printf 'hi there!\n'
hi there!
```

## <a name="another-heading"></a>Another heading

Quelques explications
```bash
$ help -d readarray
readarray - Read lines from a file into an array variable.
$ a=5
$ printf "$a\n"
5
```
  • Tout le texte est lu dans un tableau, de sorte que la ligne suivante à lire puisse être contrôlée dynamiquement.
  • Une fois une commande à tester identifiée :

    • la sortie attendue est collectée dans une variable. Les lignes multiples sont concaténées. Certaines commandes n’ont pas de sortie stdout à comparer ;
    • l’index de la prochaine itération est corrigé en conséquence.
  • Notez que ceci est un exemple de script pour démontrer l’usage de script shell. Ce n’est pas infaillible, n’a pas de contrôle poussé pour de possibles erreurs, etc.
  • Assurez-vous qu’ eval soit utilisé pour les commandes connues comme c’est le cas ici ;
  • Voir Parameter Expansion pour des exemples et explications sur le processus de construction de chaînes.
 
Sélectionnez
#!/bin/bash

cb_start=0
readarray -t lines < 'sample.md'

for ((i = 0; i < ${#lines[@]}; i++)); do
    # marque le début/la fin du bloc de commande
    # Les lignes commençant par $ seront vérifiées seulement entre ```bash et ``` block end
    [[ ${lines[$i]:0:7} == '```bash' ]] && ((cb_start=1)) && continue
    [[ ${lines[$i]:0:3} == '```' ]] && ((cb_start=0)) && continue

    if [[ $cb_start == 1 && ${lines[$i]:0:2} == '$ ' ]]; then
        cmd="${lines[$i]:2}"
        # collecte  les lignes de sortie de commande jusqu'à la ligne commençant par $ ou ``` block end
        cmp_str=''
        j=1
        while [[ ${lines[$i+$j]:0:2} != '$ ' && ${lines[$i+$j]:0:3} != '```' ]]; do
            cmp_str+="${lines[$i+$j]}"
            ((j++))
        done
        ((i+=j-1))
        cmd_op=$(eval "$cmd")
        if [[ "${cmd_op//$'\n'}" == "${cmp_str//$'\n'}" ]]; then
            echo "Pass: $cmd"
        else
            echo "Fail: $cmd"
        fi
    fi
done
  • Notez comment sourcer le script est utilisé pour prendre en considération les commandes dépendant des commandes précédentes.
 
Sélectionnez
$ ./verify_cmds.sh 
Pass: seq 3
Pass: printf 'hi there!\n'
Pass: help -d readarray
Pass: a=5
Fail: printf "$a\n"
$ source verify_cmds.sh
Pass: seq 3
Pass: printf 'hi there!\n'
Pass: help -d readarray
Pass: a=5
Pass: printf "$a\n"

8-13. Liste de ressources

Le contenu de ce chapitre n'est qu'une introduction de base.

Shell Scripting

Specific topics

Handy tools, tips and reference

9. À propos de ce document

Traduction depuis https://learnbyexample.gitbooks.io/linux-command-line/content, publié sur Gitbook.

Crédits supplémentaires :

unix.stackexchange and stackoverflow - for getting answers to pertinent questions as well as sharpening skills by understanding and answering questions

Chrtophe pour la traduction, Flodelarab pour la relecture technique, et claudeLELOUP pour la relecture orthographique.

Licence : Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Gitbook et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.