TUTORIEL SHELL     Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce manuel HTML est proposé à tous les utilisateurs du SHELL, il comprend les règles de base d'utilisation du shell avec de nombreux liens sur des pages de détail, des liens sur d'autre tutoriels, ou des pages de manuel (man) de nombreuses commandes.

Documentation protégée par licence copyleft - tous droits inversés (Voir détail en fin de document)





 1 : AIDE EN LIGNE     Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce chapitre est consacré aux généralités du SHELL.




 1.1 : MANIPULATIONS SOURIS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le SHELL, dans un terminal, n'utilise pas la souris. L'utilisateur pourra, par contre, utiliser le copier/coller, fourni par X11, pour faciliter la saisie.

Rappelons donc comment faire un copier/coller en X11.

Comment faire un copier :

     Dans la fenêtre du shell (ou une autre), positionner la souris en début de zone à coller.

     Enfoncer le bouton de gauche, et tout en le maintenant enfoncé, faire glisser la souris jusque la fin de la zone à copier.

     Relacher le bouton gauche, la zone sélectionnée est en surbrillance ou inverse vidéo.

Comment faire le coller :

     Se positionner à l'endroit où l'on désire faire le coller. Cet endroit doit être logiquement en cours de saisie. Exemple Si l'on est dans l'invite de commande (prompt) avec ou sans texte déjà saisi. Si l'on est dans une commande qui lit sur l'entrée standard, ...

     Utiliser un simple clic gauche pour définir le point d'insertion. Attention à ne pas refaire un glisser qui referait un nouveau copier et qui effacerait le précédent.

     Utiliser un simple clic sur le bouton/molette du milieu.

     Le coller doit apparaître.

Si vous avez copié une ligne jusqu'au bout, ou plus d'une ligne, la fin de chaque ligne sera considérée comme une entrée validée automatiquement par le coller. Le coller fera comme vous si vous saisissiez chaque ligne et si vous validiez chaque ligne par la touche <Entrée>.

Dans une fenêtre X11 d'autres manipulations souris sont possibles, mais elles sortent du cadre de ce manuel consacré au SHELL.




 1.2 : MANIPULATIONS CLAVIER   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Il existe un certains nombre de combinaisons claviers qui concernent le SHELL, et d'autres qui sans concerner le SHELL doivent être connues car elles peuvent interférer avec le fonctionnement du SHELL.

Certaines combinaisons peuvent différer selon le mode 'emacs' ou 'vi' de l'environnement (voir set).

La table ci-dessous présente les valeurs utilisées par défaut de bash.

  ┌────────────┬────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ <CTRL><A>  │Début ligne │  Positionne le curseur en début de ligne                                                                                           │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><C>  │SIGINT      │  Envoi du signal SIGINT pour interrompre une commande en cours.                                                                    │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><D>  │EOT         │  Si l'on est à l'invite de commande (prompt) entraîne la fermeture du shell ( ::= exit )                                           │
  │            │            │  Si l'on est dans une commande qui lit l'entrée standard, entraîne la fermeture de cette entrée standard.                          |
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><E>  │Fin de ligne│  Positionne le curseur en fin de ligne                                                                                             │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><H>  │Backspace   │  Supprime le caractère où est positionné le curseur.  ::= <Backspace>                                                              │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><K>  │Effac.ligne │  Efface les caractères à partir du curseur jusque la fin de la ligne                                                               │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><L>  │Eff.écran   │  Efface l'écran (::= clear)                                                                                                        │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤  
  │ <CTRL><N>  │Historique  │  Liste les commandes stockées dans l'historique en remontant dans le temps.                                                        │
  │            │            │  Pour exécuter la commande désirée, utiliser la touche <Entrée>, pour la sélectionner sans l'exécuter flèche gauche ou droite      │
  │            │            │  Voir aussi l'utilisation de la flèche de déplacement de curseur vers le haut.                                                     │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><P>  │Historique  │  Liste les commandes stockées dans l'historique en descendant dans le temps, à utiliser suite à un <CTRL><P> pour inverser le sens │
  │            │            │    si l'on a été trop loin.                                                                                                        │
  │            │            │  Pour exécuter la commande désirée, utiliser la touche <Entrée>, pour la sélectionner sans l'exécuter flèche gauche ou droite      │
  │            │            │  Voir aussi l'utilisation de la flèche de déplacement de curseur vers le bas.                                                      │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><Q>  │Arr.défil.  │  Après un <CTRL><S> qui a suspendu l'affichage, permet de reprendre l'affichage.                                                   │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><R>  │Historique  │  Départ d'une recherche de motif dans l'historique d'une commande pour éventuellement relancer/modifier une commande.              │
  │            │            │  Pour exécuter la commande désirée, utiliser la touche <Entrée>, pour la sélectionner sans l'exécuter flèche gauche ou droite      │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><S>  │Arr.défil.  │  Pendant l'affichage écran d'une commande en cours d'exécution, provoque l'arrêt du défilement. Voir <CTRL><Q> pour rédémarrer     │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><T>  │Invers.car. │  Inverse le caractère courant avec son précédent (pour ceux qui frappent trop vite)                                                │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><U>  │Eff.déb.lig.│  Efface les caractères à partir du début de ligne jusqu'au curseur.                                                                │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><W>  │Effac.mot   │  Efface le mot précédent le curseur si le curseur est en début de mot. Efface les caractères qui précédent le curseur si le curseur│
  │            │            │  est en milieu de mot.                                                                                                             │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><Y>  │Restauration│  Restaure le ou les caractères effacés par des commande d'effacement.                                                              │
  │            │des caract. │  Si cette fonction est opérationnelle, la description suivante 'suspension différée' ne sera pas active et inversement.            │
  │            │effacés.    │                                                                                                                                    │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><Y>  │Suspension  │  Pendant le déroulement d'une commande, permet d'envoyer cette commande en arrière plan (où elle arrivera suspendue) Voir jobs     │
  │            │différée    │  Si la tâche essai de lire l'entrée standard elle repassera en avant plan.                                                         │
  │            │            │  N'existe pas sur tous les systèmes, voir précédemment.                                                                            │
  │            │            │  Voir COMMENT LANCER UNE TÂCHE EN ARRIERE PLAN                                                                                     │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><Z>  │Suspension  │  Pendant le déroulement d'une commande, permet d'envoyer cette commande en arrière plan (où elle arrivera suspendue) Voir jobs     │
  │            │            │  Voir COMMENT LANCER UNE TÂCHE EN ARRIERE PLAN                                                                                     │
  └────────────┴────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘  

  ┌────────────┬────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ <TAB>      │Complétion  │  Si au prompt on commence à saisir le ou les premiers caractères d'une commande, la touche <TAB> permet de compléter le nom        │
  │            │nom commande│    de la commande dès lors qu'elle est unique.                                                                                     │
  │            │            │  Voir <TAB><TAB> si le ou les caractères saisis sont ambigus avec une liste de plusieurs commandes.                                │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <TAB><TAB> │Complétion  │  Si au prompt on commence à saisir le ou les premiers caractères d'une commande, la touche <TAB> suivie d'un deuxième <TAB>        │
  │            │nom commande│    permet d'obtenir la liste des commandes commençant par ce ou ces caractères. La recherche des commandes se fait en fonction de  │
  │            │            │    la variable PATH.                                                                                                               │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <TAB>      │Complétion  │  Après avoir composé le nom d'une commande, vous saisissez le nom d'un fichier (en argument de cette commande), la touche <TAB>    │
  │            │nom fichier │    permet de compléter le nom de ce fichier dès lors que vous avez saisie assez de caractère pour l'identifier sans ambiguïté.     │
  │            │            │  Voir <TAB><TAB> si le ou les caractères saisis sont ambigus avec plusieurs noms de fichiers                                       │
  ├────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <TAB><TAB> │Complétion  │  Si au prompt on a déjà saisi un nom de commande, et que l'argument de cette commande est un nom de fichier la saisie de deux      │
  │            │nom fichier │    touches <TAB><TAB> va vous permettre d'afficher la liste des noms de fichier commençant par le ou les caractères saisis pour    │
  │            │            │    spécifier le nom de fichier.  Si vous n'avez saisi aucun caractère au si le ou les caractères saisis ne commencent pas par un / │
  │            │            │    alors, la recherche se fait à partir du répertoire courant.                                                                     │
  └────────────┴────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Ces combinaisons ne sont pas liées au shell mais a l'environnement graphique. Elles peuvent servir à ouvrir une console et donc un shell.

  ┌──────────────────┬────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ <CTRL><ALT><Fn>  │ n de 1 à 6 │ Permet d'ouvrir des consoles ttyn tout en laissant la session graphique active voir <CTRL><ALT><F7> pour repasser sur la session   │
  │                  │            │   graphique.                                                                                                                       │
  │                  │            │ les valeurs 1 à 6 pour les tty et 7 pour la session graphique dépendent des systèmes.                                              │
  ├──────────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><ALT><F7>  │            │ Permet de repasser la session graphique en premier plan.                                                                           │
  │                  │            │ les valeurs 1 à 6 pour les tty et 7 pour la session graphique dépendent des systèmes.                                              │
  ├──────────────────┼────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><ALT><Fn>  │ n > 7      │ Permet de voir les autres serveurs graphiques si on dispose de plusieurs serveurs X en même temps.                                 │
  │                  │            │ les valeurs au delà de 7 dépendent de la configuration des serveurs X et du système.                                               │
  └──────────────────┴────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Ces combinaisons ne sont pas liées au shell mais a l'environnement graphique. Elle peuvent être utiles dans le cadre de toute session graphique.

  ┌────────────────────────┬────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ <CTRL><ALT><Suppr>     │Destruction │ Cette combinaison qui séduira peut-être les nostalgiques des PC sous DOS ou Windows permet de re-démarrer le      │
  │                        │du serveur X│  système (reboot).  Pour des raisons de sécurité cette combinaison est souvent interceptée et ne réagit pas.      │
  │                        │            │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><ALT><Backspace> │Destruction │ Cette combinaison détruit le serveur X. A n'utiliser que si la session graphique ne répond plus correctement.     │
  │                        │du serveur X│                                                                                                                   │
  │                        │            │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><ALT><D>         │Réduc/Rest. │ Permet la réduction de toutes les fenêtres actives. A l'alternat, elle restaure les fenêtres ayant été réduites.  │
  │                        │des fenêtres│                                                                                                                   │
  │                        │actives     │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <CTRL><ALT><+>         │Changement  │ Si votre configuration X11 prévoit plusieurs résolutions, ces combinaisons permettent le passage d'une résolution │
  │ <CTRL><ALT><->         │résolution  │   à une autre.                                                                                                    │
  │                        │            │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <ALT><TAB>             │Défilement  │ Ces combinaisons permettent de voir dans une petite fenêtre les fenêtre actives et de sélectionner celle que l'on │
  │ <ALT><SHIFT><TAB>      │des fenêtres│   désire mettre en avant plan.                                                                                    │
  │                        │            │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <ALT><F2>              │Lancement   │ Cette combinaison ouvre une commande dans laquelle on pourra saisir une commande à exécuter.                      │
  │                        │ commande   │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <ALT><F4>              │Fermeture   │ Cette combinaison ferme ou essaie de fermer la fenêtre en cours                                                   │
  │                        │ fenêtre    │                                                                                                                   │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <ALT><Bouton-G>        │Déplacement │ Cette combinaison permet de déplacer une fenêtre (si on ne peut plus le faire dans la barre de fonctions de la    │
  │                        │ fenêtre    │   fenêtre.                                                                                                        │
  │                        │            │ Dans certains cas la fenêtre sera réduite avant d'être déplacée.                                                  │
  ├────────────────────────┼────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ <ALT><Bouton-D>        │Menu        │ Cette combinaison fait apparaître le menu lié à une fenêtre.                                                      │
  │                        │ fenêtre    │                                                                                                                   │
  └────────────────────────┴────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Il existe bien sûr d'autre combinaisons, mais elles dépendent de l'environnement graphique (gnome, kde, ...) et donc sortent du cadre de ce manuel.




 1.3 : AIDE EN LIGNE (man)    Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

L'aide en ligne de LINUX s'obtient avec la commande 'man'.

Ce manuel est directement inspiré du résultat des commandes les plus courantes décrites dans 'man' mais remises en forme plus agréable.

Les commandes importantes sont découpées en sous-chapitres afin de faciliter un accès par table des matières, table des mots-clés, à une information partielle concernant une commande.

Une commande, comme 'sh' (SHELL), est décrite globalement sous 'man', alors que dans ce manuel, elle fera l'objet de 46 sous-chapitres distincts.

De plus, pour les commandes simples comportant un ou plusieurs exemples simples d'utilisation, ces exemples seront dans le chapitre de la commande elle-même. Pour des commandes plus complexes un chapitre spécial sera consacré aux exemples détaillés de ces commandes.

('sort', 'gawk', etc...)

L'aide en ligne avec 'man'.




 1.3.1 : AIDE EN LIGNE LINUX DE BASE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

La documentation des autres commandes est accessible avec 'man'.

Lorsque l'on connaît le nom d'une commande, il sera possible d'utiliser la commande 'man' sans option avec comme argument le nom de la commande désirée.

Mais la commande 'man' possède aussi des options qui permettent de faire des recherches sur les noms de commande ou les intitulés de commande.

Exemple :

  ┌──────────────────┐       ┌───────────────────┐
  │ man -k directory │  ::=  │ apropos directory │  ::= Affiche :
  └──────────────────┘       └───────────────────┘
  ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │alphasort []         (3)  - scan a directory for matching entries                                                                    │
  │basename []          (1)  - strip directory and suffix from filenames                                                                │
  │cd []                (1p)  - change the working directory                                                                            │
  │cd []                (n)  - Change working directory                                                                                 │
  │chacl []             (1)  - change the access control list of a file or directory                                                    │
  │chdir []             (3p)  - change working directory                                                                                │
  │chooseDirectory []   (3)  - pops up a dialog box for the user to select a directory                                                  │
  │chroot []            (1)  - run command or interactive shell with special root directory                                             │
  │chroot []            (2)  - change root directory                                                                                    │
  │closedir []          (3)  - close a directory                                                                                        │
  │closedir []          (3p)  - close a directory stream                                                                                │
  │cups []              (1)  - config - get cups api, compiler, directory, and link information                                         │
  │curlftpfs []         (1)  - mount a ftp host as a local directory                                                                    │
  │Cwd []               (3)  - get pathname of current working directory                                                                │
  │Cwd                  (3pm)  - get pathname of current working directory                                                              │
  │dbus []              (1)  - cleanup-sockets - clean up leftover sockets in a directory                                               │
  │depmod.conf []       (5)  - Configuration file/directory for depmod                                                                  │
  │depmod.d []          (5)  - Configuration file/directory for depmod                                                                  │
  │dir []               (1)  - list directory contents                                                                                  │
  │dirent.h []          (0p)  - format of directory entries                                                                             │
  │dirfd []             (3)  - get directory stream file descriptor                                                                     │
  │DirHandle []         (3)  - supply object methods for directory handles                                                              │
  │dirname []           (1p)  - return the directory portion of a pathname                                                              │
  │dirsplit []          (1)  - splits directory into multiple with equal size                                                           │
  │..........................                                                                                                           │
  │....................................                                                                                                 │
  └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

La mention entre () qui suit le nom d'une commande est la 'section' à laquelle cette commande appartient. Il existe huit 'sections' de base.

      ┌──────────────────────────────────────────────────────────────────┐
      │(1) ::= Commandes accessibles à l'utilisateur                     │
      │(2) ::= Interface entre LINUX et les programmes 'C'               │
      │(3) ::= Bibliothèques 'C', y compris 'stdio.h' et 'math.h'        │
      │(4) ::= Caractéristiques des fichiers systèmes et périphériques   │
      │(5) ::= Extensions compilation 'C'                                │
      │(6) ::= Les jeux                                                  │
      │(7) ::= Les commandes liées aux entrées/sorties                   │
      │(8) ::= Les commandes de maintenance du système                   │
      └──────────────────────────────────────────────────────────────────┘

Si une 'section' comporte des variantes (posix par exemple) elle contient une 'sous-sections' comme par exemple la 'section 3p' (Bibliothèque 'C' POSIX) :

       ┌───────────────────────────────────────────────────────────┐
       │(1p)  ::=  Commandes utilisateur POSIX                     │
       │(3p)  ::=  Bibliothèque 'C' Posix                          │
       └───────────────────────────────────────────────────────────┘

Les commandes standard sont documentées à partir de fichiers situés dans l'arborescence '/usr/share/man'.

lié à cette commande. Dans certains cas deux commandes différentes peuvent avoir un même fichier d'aide en ligne.

Il peut s'agir de variantes de la même commande (Exemple 'awk' et 'gawk', 'sh' et 'bash' ) ou de commandes regroupées dans la même page (Exemple : islower, isascii, isxxxxx) .




 1.3.1.1 : man  AFFICHAGE DOCUMENTATION COMMANDE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

NOM
 ┌────────────────────────────────────────────────────────────────────────┐
 │ man ::=  Affichage documentation en ligne d'une ou plusieurs commandes │
 └────────────────────────────────────────────────────────────────────────┘

SYNOPSIS
   ┌──────────────────────────────────────────────┐
   │ man [-s section]] nom_cde ...                │
   │                                              │
   │ man -k critère_de_recherche ...              │   ::=  apropos
   │                                              │
   │ man -f critère_de_recherche ...              │   ::=  whatis 
   └──────────────────────────────────────────────┘

Les options '-k' ou '-f' ne sont pas des options de consultation de détail d'une commande, mais correspondent à des sélections sur les noms de commandes ou les intitulés des commandes dont il existe une documentation en ligne de façon à afficher les commandes sélectionnées à raison d'une par ligne. L'utilisateur peut ensuite faire son choix dans la liste proposée et appeler la commande 'man xxxxx' avec le nom de la commande désirée.

Ces options ou les alias apropos et whatis sont basés sur une base de données /var/cache/man/whatis créée mat la commande 'makewhatis -w'

DESCRIPTION Sans option la commande 'man' attend le ou les noms des commandes dont on désire afficher la documentation.

Cet affichage se fait par défaut avec 'less' (voir commande 'less'), mais on pourra utiliser un 'pipe' pour diriger l'affichage dans une tâche du spouleur, exemple :

                  ┌──────────────┐
                  │ man ls | lp  │
                  └──────────────┘

Si l'on désire supprimer les caractères gras et sous-lignés :

                  ┌─────────────────┐
                  │ man ls | col -b │
                  └─────────────────┘

OPTIONS AFFICHAGE DETAIL COMMANDE

-a Affichera les pages de toutes les sections où la commande est documentée au lieu de s'arrêter à la première section pour laquelle la commande désirée existe.

Cette option est intéressante pour des commandes appartenant à plusieurs groupes.

-s Affichera la documentation concernant la section 'x' de la commande spécifiée. Cette option est intéressante pour des commandes appartenant à plusieurs sections.

Exemple :

    ┌─────────────────┐
    │ man -a printf   │        Affichage de la commande 'printf (1)' utilisable sous SHELL et de la fonction 'printf (3)' utilisable en 'C'.
    └─────────────────┘     
    ┌─────────────────┐
    │ man -s 3 printf │   Affichage uniquement de la fonction
    └─────────────────┘     'printf (3)' utilisable en 'C'.

chemin_nom_fichier Cette option permet de spécifier le nom du fichier dont on désire consulter le contenu. Dans ce cas on ne passe pas par le nom d'une commande pour identifier un fichier contenant le détail de cette commande, mais on indique directement le nom du fichier.

Exemple : 'man /usr/share/man/man1p/ls.1p.gz'.

OPTIONS SELECTION NOM/INTITULE

Ces options utilisent la notion d'expression régulière complète qui permet de définir un critère de recherche qui dans les cas simples sera une sous-chaîne de caractères à rechercher.

-f mot_recherché ... le mot exact est recherché dans la lsite des nom de commandes.

  ┌─────────────────┐  ┌─────────────────────────────────────────────────────────────────────┐
  │ man -f printf   │  │ printf []            (1)  - bash built-in commands, see bash(1)     │   Commande interne du shell en français
  └─────────────────┘  │ printf []            (1)  - format and print data                   │   Commande interne du shell en anglais
                       │ printf []            (1p)  - write formatted output                 │   Fonction POSIX 
                       │ printf []            (3)  - Formatage des sorties                   │   Fonction 'C' en français
                       │ printf []            (3)  - formatted output conversion             │   Fonction 'C' en anglais
                       │ printf []            (3p)  - print formatted output                 │   Fonction 'C' POSIX
                       └─────────────────────────────────────────────────────────────────────┘

-k expression_régulière Recherche de l'expression régulière sur les noms et les intitulés de commande.

Cette option pourra être utilisée pour rechercher des commandes en indiquant un critère de recherche sur l'intitulé de la commande.

Cette commande équivaut à la commande 'apropos'.

Le critère de recherche est utilisé en tant qu'expression régulière (voir la commande grep ou le tutoriel expressions régulières).

Mais il ne s'agit pas d'expressions régulières complètes mais d'expressions régulières simples.

affi.*fuseau ::= Recherchera aussi bien 'Affichage fuseau' que 'Afficher les fuseaux'

              ┌───────────────┐
    Exemple : │ man -k fuseau │  affichera
              └───────────────┘
              ┌───────────────────────────────────────────────────────────────────────────┐
              │tzfile []            (5)  - Information de fuseau horaire                  │
              │tzselect []          (1)  - Afficher les fuseaux horaires                  │
              │tzselect []          (8)  - Sélectionner un fuseau horaire                 │
              │zdump []             (8)  - Affichage du fuseau horaire                    │
              │zic []               (8)  - Compilation des informations de fuseau horaire │
              └───────────────────────────────────────────────────────────────────────────┘

Mais attention, si vous disposez de pages françaises, il ne faut pas oublier que toutes les pages ne sont pas traduites. Il faudra penser à recherche aussi les pages anglaises.

              ┌────────────────────┐
    Exemple : │ man -k time zone   │  affichera la liste des commande ayant 'time' OU 'zone' (556 lignes).
              └────────────────────┘

              ┌────────────────────┐
    Exemple : │ man -k 'time zone' │  affichera
              └────────────────────┘
              ┌────────────────────────────────────────────────────────┐
              │mysql_tzinfo_to_sql  (1)  - load the time zone tables   │
              │tzfile []            (5)  - time zone information       │
              │tzselect []          (8)  - select a time zone          │
              │zdump []             (8)  - time zone dumper            │
              │zic []               (8)  - time zone compiler          │
              └────────────────────────────────────────────────────────┘

                                    ┌─────────────────────────────┐
    Exemple de recherche bilingue : │ man -k 'time zone' fuseau   │
                                    └─────────────────────────────┘
              ┌───────────────────────────────────────────────────────────────────────────┐
              │mysql_tzinfo_to_sql [] (1)  - load the time zone tables                    │
              │tzfile []            (5)  - Information de fuseau horaire                  │
              │tzfile []            (5)  - time zone information                          │
              │tzselect []          (1)  - Afficher les fuseaux horaires                  │
              │tzselect []          (8)  - select a time zone                             │
              │tzselect []          (8)  - Sélectionner un fuseau horaire                 │
              │zdump []             (8)  - Affichage du fuseau horaire                    │
              │zdump []             (8)  - time zone dumper                               │
              │zic []               (8)  - Compilation des informations de fuseau horaire │
              │zic []               (8)  - time zone compiler                             │
              └───────────────────────────────────────────────────────────────────────────┘

En utilisant la notion d'Expression Régulière Complète on aurait pu combiner une recherche sur 'editor' et 'grep' en utilisant :

'man -k "grep|editor"' ou plus simplement en utilisant deux critères de recherche comme dans 'man -k grep editor'.

Les recherches '-k' et '-f' utilisent un 'egrep -i' (qui ne distingue pas les minuscules des MAJUSCULES) dans '/usr/share/man/mrd/mandb'.

Dans ce fichier la 'section' est séparée du nom de la commande par un espace, mais non encadrée par des ().

On peut donc faire des recherches du style 'man -k 3G' pour obtenir toutes les commandes (3G).

ENVIRONNEMENT

La configuration de man se trouve dans le fichier '/etc/man.config' qui contient les paramètres de man (et l'on peut forcer la valeur de certains paramètres en utilisant des variables d'environnement du même nom) .

'MANPATH' Cette variable contient le path de recherche des manuels. Par défaut il s'agit de : '/usr/share/man/mrd:/usr/share/man'.

'PAGER' Programme permettant l'affichage interactif du détail d'une commande.

Par défaut il s'agit de 'less -is' options -is :: On ignore la différence Majuscule/Minuscule pour les recherches de chaînes et l'on n'affiche pas les lignes vides successives, mais une seule. (voir 'less ').

FICHIERS
   ┌───────────────────────────────────────────────────────────────────────┐
   │ /usr/share/man/mrd       Manuels en ligne                             │
   │ /usr/share/man/catman    Manuels en ligne comprimés.                  │
   │ /usr/share/man/.mandb/*  Manuels fournis en même temps qu'un logiciel │
   │ /usr/share/man/mandb     Base de données des manuels en ligne.        │
   └───────────────────────────────────────────────────────────────────────┘




 2 : SYSTEMES DE FICHIERS SOUS LINUX   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Sous LINUX les fichiers sont stockés dans des répertoires constituant une structure hiérarchique ou encore une arborescence :

          ┌────────
          ├──bin/
          ├──boot/
          ├──etc/
        /─┼──home/
          ├──usr/
          │   └───>/usr/bin
          ├──var/
          └────────

On part d'un répertoire de base '/' (appelé 'racine') et qui contient des fichiers ou des sous-répertoires qui contiennent eux aussi des fichiers ou des sous-répertoires.

Chaque répertoire possède un répertoire 'père' et peut posséder un certain nombre de répertoires 'fils'.

Lors de la création d'un répertoire (voir commande 'mkdir') il y a systématiquement création de deux entrées appelées '.' et '..' :

                ┌────────────────────────────────────┐
                │ .     ::= Le répertoire lui-même   │
                │ ..    ::= Le répertoire père       │
                └────────────────────────────────────┘

Lorsque l'on a besoin de spécifier un nom de fichier on pourra le faire :

- En absolu ::= A partir de la 'racine' sous la forme /usr/bin/ls

- En relatif ::= A partir du répertoire courant, sous la forme './bin/ls' est équivalent à '/usr/bin/ls' si l'on est déjà dans '/usr'.

- En direct ::= Uniquement le nom du fichier et dans ce cas ce nom est recherché dans le répertoire courant sauf pour un nom de commande ou d'exécutable. Si un nom de commande ne contient aucun '/' la commande est recherchée dans la table 'hash' ou tous les répertoires contenus dans la variable d'environnement PATH (voir le chapitre 'EXECUTION COMMANDE').

- En semi-direct ::= 'xxxx/nom_fic' va chercher à partir du répertoire courant le sous-répertoire 'xxxx' et va y rechercher le fichier spécifié.

La découpe des répertoires et le choix de mettre un fichier dans tel ou tel répertoire suit (normalement) une norme, mais comme souvent il y a plusieurs interprétations de cette norme.

Pour les Unix et les Linux qui suivent la norme FHS voir Wikipedia Filesystem Hierarchy Standard

Pour Linux voir FHS pour Linux




 2.1 : PARTITIONS DISQUE / FILE-SYSTEM   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Un répertoire ne peut pas s'étaler sur plusieurs disques.

Pour des raisons de sécurité et de facilités de sauvegardes il est intéressant de découper un disque physique en plusieurs partitions indépendantes.

Pour ces deux raisons on utilise la notion de 'file-system' qui va permettre un découpage d'un disque physique en partitions logiques et d'associer ces partitions à des répertoires.

Le ou les disques sont découpés logiquement en 'file-system'. Chaque 'file-system', au moment du démarrage normal de la machine, vient se substituer à un des sous-répertoires contenus à partir de la racine.

Cette opération s'appelle le montage d'un disque et ce montage se fait en fonction du fichier '/etc/fstab' qui associe des 'file-system' à des répertoires qui après montage contiendront l'espace disque prévu pour le 'file-system'. Le fichier '/etc/mtab' contient la liste des 'file-system' montés.

Un 'file-system' est défini, lors de sa création, avec une certaine taille disque ainsi qu'un certain nombre de points d'entrée pouvant stocker les caractéristiques des fichiers que l'on créera dans ce 'file-system'. Ces points d'entrée sont appelés 'I-node'.

Chaque fichier stocké sur disque est associé à un 'I-node' qui contient les caractéristiques physiques de ce fichier.

La commande 'df' permet de visualiser la liste des 'file-system' montés et donc disponibles, ainsi que des informations (selon les options) sur la place disponible dans ces 'file-system' (Voir commande 'df').

                             ┌───────┐
  Exemple de commande        │ df -k │
                             └───────┘
 ┌────────────────────────────────────────────────────────────────────────┐
 │ filesystem                kbytes     used    avail capacity mounted on │
 │ /dev/sda1                  55044    40904     8634    83%   /          │
 │ /dev/sda2                 196208   120318    56268    68%   /home      │
 │ /dev/sda3                2196008  2120318   256268    68%   /data      │
 └────────────────────────────────────────────────────────────────────────┘

Le 'file-system' '/' est le 'file-system' de base qui contient des répertoires sur lesquels sont montés d'autres 'file-system'.

Les noms '/home', etc... sont des 'file-system' et non pas des simples répertoires de la racine '/'.




 2.2 : TYPES DE FICHIERS LINUX   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Les fichiers gérés par LINUX sont de différentes sortes :

     ┌─────────────────────────────────────┐
     │  Fichiers répertoires               │
     │  Fichiers de données (réguliers)    │ Les fichiers réguliers snt des fichiers de donénes ou des exécutables en fonction de leurs droits et de leur contenu.
     │  Fichiers spéciaux (périphériques)  │
     │  Fichiers liens symboliques         │
     │  Fichiers 'pipe'                    │
     │  Fichiers 'socket'                  │
     └─────────────────────────────────────┘

Chacun de ces fichiers est créé par une commande spécifique à son type.

Cette création utilise une entrée appelée 'I-node' dans le 'file-system' concerné. Cet 'I-node' contient les caractéristiques du fichier.

Un 'file-system' est prévu lors de sa création pour contenir un certain nombre d' I-nodes, donc de fichiers.


NOMS DE FICHIERS SOUS LINUX :

Sous LINUX les noms de fichiers sont très libres. On peut utiliser n'importe quel caractère sauf le '/' qui est utilisé pour séparer un nom de répertoire d'un nom de fichier. Mais en pratique il faudra se garder d'utiliser les caractères spéciaux du SHELL (?,*,[,],|,;,>,<,...) pour pouvoir manipuler ces noms de fichier sans ambiguïté.

Il vaut mieux respecter une convention qui veut que l'on n'utilise que des lettres, chiffres et les caractères '.', ',', '-' ou '_'.

Le premier caractère est libre (lettre, chiffre ou même caractère spécial) mais si un nom de fichier commence par un '.', alors il est considéré comme 'caché' et, avec certaines commandes, ne fait partie des fichiers accessibles qu'avec certaines options (Exemple 'ls -a').

De plus les options de commandes commençant par un '-' il est peu commode pour certaines commandes de distinguer les options et les noms de fichiers commençant par '-'.

Voir aussi le chapitre NOMS DE FICHIERS INHABITUELS.


REPERTOIRES : Fichiers répertoires : Ce sont des fichiers contenant la liste des noms de fichiers ou de répertoires qu'il contient.

Ces fichiers sont créés par la commande 'mkdir' (voir la commande 'mkdir').

Lors de la connexion d'un utilisateur, celui-ci se trouve normalement dans un répertoire qui lui appartient (appelé 'home-directory') et dans lequel il peut normalement faire ce qui lui plaît.

On passe d'un répertoire à un autre avec la commande 'cd' et l'on vérifie le répertoire où l'on se trouve avec la commande 'pwd'.

Un répertoire est constitué des noms de fichiers qu'il contient et des numéros d'I-node de ces fichiers.

     ┌─── Exemple d'affichage par 'ls' de fichiers répertoire  ───────┐
     │drwxr-xr-x  33 root     root        3072 Aug 11 19:44 /etc      │
     │drwxr-xr-x   4 root     root        6656 May 27 18:11 /usr/bin  │
     └────────────────────────────────────────────────────────────────┘


FICHIERS DE DONNEES :

Fichiers de données ou fichiers exécutables : Ils sont stockés par LINUX dans un répertoire et sont vus par LINUX comme une suite d'octets.

On parle aussi de 'fichiers réguliers' ('regular file').

Ces fichiers sont créés par des éditeurs LINUX, des compilateurs ou par l'exécution de commandes ou de programmes.

Il est à noter que LINUX ne fait pas de différence entre fichier de données et exécutables en ce qui concerne le stockage sur disque et dans un répertoire.

Seule la commande 'chmod' permet de distinguer après création si un fichier doit être considéré comme exécutable ou non (voir la commande 'chmod').

    ┌───  Exemple d'affichage par 'ls' de fichiers réguliers  ────────────┐
    │ -rw-rw----   1 xbasic   xbasic       348 Aug 12 02:53 /u0/usr/toto  │
    │ -rwxrwxrwx   1 xbasic   xbasic       120 Aug 12 00:13 /u0/usr/titi  │
    └─────────────────────────────────────────────────────────────────────┘

toto est un fichier de données de 348 octets.

titi est un fichier exécutable de 120 octets.


FICHIERS SPECIAUX :

Fichiers spéciaux : Ce sont des fichiers chargés de gérer des périphériques et ils sont généralement stockés dans '/dev'.

Les paramètres 'Major'/'Minor' qui sont définis pour chaque fichier spécial permettent de définir quel 'driver' sera chargé de gérer le périphérique et sur quelle sortie physique.

On distingue deux types de fichiers spéciaux :

Type bloc : Travaillant avec un facteur de blocage Type caractère : Travaillant caractère par caractère.

     ┌───  Exemple d'affichage par 'ls' de fichiers spéciaux   ────────────┐
     │ crw-rw-rw-   4 root  disk  5,768 Aug 12 03:36 /dev/sda1             │
     │ crw-rw-rw-   1 root  disk  5,769 Mar  3 14:00 /dev/sda2             │
     │ crw-rw-rw-   1 root  disk  5,771 Sep 22 14:00 /dev/sda3             │
     │ brw-rw-rw-   3 root  disk  5,770 Jan  6 14:00 /dev/stty1            │
     │ brw-rw-rw-   1 root  disk  5,768 Sep 22 14:00 /dev/stty2            │
     └─────────────────────────────────────────────────────────────────────┘

Ces fichiers sont créés au boot par 'udev' ou par la commande 'mknod'. Mais ceci sort du cadre de ce manuel (Voir l'administrateur système).


LIENS SYMBOLIQUES :

Liens symboliques : Ce sont des fichiers qui pointent en fait sur un autre fichier.

     ┌──    Exemple d'affichage par 'ls' de lien symoblique   ────────────────┐
     │lrwxrwxrwx  1 root root    7 sep 25 11:10 rc -> rc.d/rc                 │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc0.d -> rc.d/rc0.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc1.d -> rc.d/rc1.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc2.d -> rc.d/rc2.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc3.d -> rc.d/rc3.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc4.d -> rc.d/rc4.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc5.d -> rc.d/rc5.d           │
     │lrwxrwxrwx  1 root root   10 sep 25 11:10 rc6.d -> rc.d/rc6.d           │
     │lrwxrwxrwx  1 root root   13 sep 25 11:10 rc.local -> rc.d/rc.local     │
     │lrwxrwxrwx  1 root root   15 sep 25 11:10 rc.sysinit -> rc.d/rc.sysinit │
     └────────────────────────────────────────────────────────────────────────┘

Dans ce cas le fichier 'rc0.d' fera référence au fichier 'rc.d/rc0.d' par l'intermédiaire du lien symbolique.


FICHIERS PIPE (FIFO) :

Fichiers 'pipe' ou 'FIFO' : Ce sont des fichiers créés par des commandes afin de permettre des communications de données de type 'FIFO' ('First In First Out') entre deux programmes.

     ┌────────── Exemple d'affichage par 'ls' de fichiers 'pipe-nommés'  ────────────┐
     │prw-------   1 root     root   0 Aug 11 19:43 /var/spool/postfix/public/pickup │
     └───────────────────────────────────────────────────────────────────────────────┘

La commande 'ls -l' permet de distinguer ces différents types de fichiers en affichant le 'mode' de chaque fichier traité. La première lettre de ce mode indique le type de fichier :

   ┌───────────────────────────────────────────────────────────┐
   │ drwxr-xr-x     ::=  Fichier répertoire (d::=directory)    │
   │ brw-rw-rw-     ::=  Fichier spécial de type 'bloc'        │
   │ crw-rw-rw-     ::=  Fichier spécial de type 'caractère'   │
   │ -rw-------     ::=  Fichier de données                    │
   │ -rwx------     ::=  Fichier exécutable                    │
   │ lrw-rw-rw-     ::=  Lien symbolique                       │
   │ prw-rw-rw-     ::=  Fichier pipe nommé (FIFO)             │
   │ srw-rw-rw-     ::=  Fichier socket                        │
   └───────────────────────────────────────────────────────────┘

Pour plus d'informations, voir la commande 'ls'.

Taille des fichiers sur disque :

Les fichiers autres que les fichiers spéciaux sont stockés sur disque sous forme d'octets consécutifs. Chaque fois qu'un fichier s'agrandit sur disque, il le fait dans des blocs du disque. La taille des blocs disque dépend du 'file-system' dans lequel le fichier est stocké.

Si un bloc fait 2048 octets le fichier occupe un bloc tant que sa taille ne dépasse par 2048 octets mais le 2049ème octet aura besoin d'un bloc supplémentaire et la taille disque disponible diminue d'un bloc lors de l'ajout de ce caractère et ainsi de suite, par paquet de 2048 caractères.




 2.2.1 : STRUCTURE D'UN 'I-NODE' 'ext2'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

FICHIERS REGULIERS ET REPERTOIRES

 ┌─────────────────────────────────────────────────┐
 │  Mode et type du fichier                        │ 'drwx------ -rwxr x---'
 ├─────────────────────────────────────────────────┤
 │  Nombre de liens sur le fichier                 │
 ├─────────────────────────────────────────────────┤
 │  Nom d'utilisateur propriétaire                 │
 ├─────────────────────────────────────────────────┤
 │  Nom de groupe propriétaire                     │
 ├─────────────────────────────────────────────────┤
 │  Nombre d'octets du fichier                     │
 ├─────────────────────────────────────────────────┤
 │  Date dernier accès fichier                     │ 'ls -u', 'find -atime'
 ├─────────────────────────────────────────────────┤
 │  Date dernière modification fichier             │ 'ls -t', 'find -mtime'
 ├─────────────────────────────────────────────────┤
 │  Date dernière modification I-node              │ 'ls -c', 'find -ctime'
 ├─────────────────────────────────────────────────┤
 │  10 pointeurs blocs données                     │
 ├─────────────────────────────────────────────────┤
 │  1 pointeur d'indirection simple                │
 ├─────────────────────────────────────────────────┤
 │  1 pointeur de double indirection               │
 ├─────────────────────────────────────────────────┤
 │  1 pointeur de triple indirection               │
 ├─────────────────────────────────────────────────┤
 │  Nombre d'entrées valides dans le répertoire    │
 ├─────────────────────────────────────────────────┤
 │  Nombre de blocs actuellement occupés           │
 └─────────────────────────────────────────────────┘

FICHIERS SPECIAUX

  ┌─────────────────────────────────────────────────┐
  │  Mode et type du fichier                        │
  ├─────────────────────────────────────────────────┤
  │  Nombre de liens sur le fichier                 │
  ├─────────────────────────────────────────────────┤
  │  Nom d'utilisateur propriétaire                 │
  ├─────────────────────────────────────────────────┤
  │  Nom de groupe propriétaire                     │
  ├─────────────────────────────────────────────────┤
  │  Nombre d'octets du fichier                     │
  ├─────────────────────────────────────────────────┤
  │  Date dernier accès fichier                     │
  ├─────────────────────────────────────────────────┤
  │  Date dernière modification fichier             │
  ├─────────────────────────────────────────────────┤
  │  Date dernière modification I-node              │
  ├─────────────────────────────────────────────────┤
  │  Numéro majeur (major mode) du device           │
  ├─────────────────────────────────────────────────┤
  │  Numéro mineur (minor mode) du device           │
  ├─────────────────────────────────────────────────┤
  │  pointeurs inutilisés ...                       │
  └─────────────────────────────────────────────────┘




 2.2.2 : STRUCTURE D'UN REPERTOIRE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Chaque fichier contenu dans un répertoire correspond à une entrée dans ce répertoire.

Ce chapitre présente la structure d'un fichier répertoire dans un 'file-system' de type 'ext2' (le plus couramment utilisé)

La structure de chaque entrée est :

        ┌────────────────────────────────────────┐
        │ Numéro de l'I-Node (4 octets)          │
        ├────────────────────────────────────────┤
        │ Longueur de l'entrée (2 octets)        │
        ├────────────────────────────────────────┤
        │ Longueur du nom de fichier (2 octets)  │
        ├────────────────────────────────────────┤
        │ Nom du fichier (<=255 octets)          │
        └────────────────────────────────────────┘

Un répertoire contient dès sa création deux entrées pour les répertoires '.' et '..', puis s'agrandir au fur et à mesure de la création de fichiers.

      ┌── Fichier répertoire ─────────────┐
      │ 11      9       1       .         │ Entrée du répertoire courant
      │ 2       10      2       ..        │ Entrée du répertoire père
      │ 15      13      5       memos     │ Entrée du fichier 'memos'
  ┌──── 16      17      9       telephone │ Entrée du fichier 'telephone'
  │   │ 17      14      6       .bashrc   │ Entrée du fichier '.bashrc'
  │   └───────────────────────────────────┘
  │
  │        Table I-node
  │   ┌────────────────────────┐
  │   │ 1                      │   Fichier 'telephone'
  │   │ 2                      │      ┌───────┐
  │   │ .......                │   ┌──┤données│
  │   │15                      │   │  └───────┘
  └────16 ─────────────────────────┤
      │17                      │   │  ┌───────┐
      └────────────────────────┘   └──┤données│
                                      └───────┘




 3 : SHELL sh bash   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce chapitre traitera du SHELL :

Utilisé pour l'appel de commandes.

Utilisé par des scripts SHELL.

Le SHELL est l'appellation LINUX du langage de commandes.

Mais en fait on peut parler d'un véritable langage de programmation comme on le verra par la suite.

Il existe plusieurs SHELL (sh, bash, ksh, tcsh, ...) mais ce tutoriel est basé sur le manuel bash (sh est une variante de bash, pour des compatibilités antérieures).

Le SHELL interprète et contrôle l'exécution de commandes.

Les commandes peuvent être composées de façon interactive à partir d'un terminal.

Les commandes peuvent être contenues dans un fichier et dans ce cas le SHELL traitera ces commandes en 'batch'. On parlera souvent dans ce cas de 'scripts SHELL' ou de 'procédures SHELL'.

Il existe plusieurs types de commandes :

  ┌────────────────────┐
  │ Commandes internes │ : Il s'agit de commandes propres au SHELL
  └────────────────────┘   (Exemple : 'cd', 'echo', etc...).
         ┌───────────────────────────────────────────┐
         │ 'type cd' affiche 'cd is a shell builtin' │
         └───────────────────────────────────────────┘

  ┌─────────────────┐
  │ Fonctions SHELL │    : Il s'agit de fonctions définies par
  └─────────────────┘      l'utilisateur (voir FONCTIONS SHELL).
         ┌──────────────────────────────────────────────────────┐
         │ 'type nom_fct'  affiche 'nom_fct is a function ....' │
         └──────────────────────────────────────────────────────┘

  ┌────────────────────┐
  │ Commandes externes │ : Il s'agit de programmes exécutables qui se trouvent répartis dans différents répertoires '/bin', '/usr/bin', etc..., (Exemple : 'ls', 'cat', etc...).
  └────────────────────┘  

         ┌─────────────────────────────────────────────┐
         │ 'type ls'  affiche 'ls is /bin/ls'          │
         │            ou      'ls is hashed (/bin/ls)' │
         └─────────────────────────────────────────────┘

  ┌───────────────┐
  │ Scripts SHELL │      : Il s'agit de fichiers contenant des
  └───────────────┘        commandes SHELL qui seront interprétées par le

SHELL, (Exemple : 'whatis', etc...).

        ┌───────────────────────────────────────────────────────────────┐
        │ 'type whatis' affiche 'basename is /usr/bin/whatis'           │
        │               ou      'basename is hashed (/usr/bin/whatis)   │
        └───────────────────────────────────────────────────────────────┘

La différence entre 'commandes externes' (programmes compilés exécutables) et les scripts SHELL est dans la façon dont ils ont été écrits.

Voir la commande file qui en examinant le début d'un fichier en déduit son type exact.

L'appel d'un programme externe ou d'un script shell se fait de la même façon.

En plus de ces commandes, le SHELL possède aussi des commandes de type programmation instructions ('for', 'if', etc...) qui sont reconnues comme telles si elles sont utilisées en début de commande.

(Ces instructions sont détaillées dans le chapitre 'INSTRUCTIONS DE PROGRAMMATION').

Un programme LINUX s'exécute à l'intérieur d'un processus.

Lors de la connexion d'un terminal un processus est créé pour recevoir normalement le SHELL et c'est à partir de ce processus que des commandes ou des programmes pourront être exécutés.

La plupart du temps un exécutable est exécuté dans un processus 'fils' et à la fin de l'exécution on revient au processus 'père'.

Le contrôle du déroulement d'un processus ou l'interprétation de commandes se fait dans un environnement constitué principalement de variables d'environnement. Ces variables sont les seules variables que connaisse le SHELL en tant qu'interpréteur ou langage de programmation.

Ces variables ne sont que d'un seul type : alphanumérique. Mais si des variables ne contiennent que des caractères numériques elles pourront être traitées par des instructions arithmétiques.

Chaque processus possède son environnement, hérité du processus 'père', (voir la commande 'export') et dispose de trois fichiers d'entrée/sortie :

        ┌───────────────────────────────────────────────────────┐
        │  Entrée standard : Par défaut le clavier du terminal  │
        │  Sortie standard : Par défaut l'écran du terminal     │
        │  Sortie d'erreur : Par défaut l'écran du terminal     │
        └───────────────────────────────────────────────────────┘

Chaque processus en cours est identifié par :

        ┌──────────────────────────────────────────────────────────┐
        │  Un numéro de processus                                  │
        │  Un numéro d'utilisateur                                 │
        │  Un numéro de groupe                                     │
        │  Un terminal (si le processus s'exécute sur un terminal) │
        │  Un programme à exécuter                                 │
        └──────────────────────────────────────────────────────────┘

Dans les commandes traitant un ou plusieurs fichiers en entrée, l'absence de spécification de fichier est souvent interprétée comme devant traiter l'entrée standard. Dans ce cas le curseur est en attente de caractères et l'on valide ligne par ligne les données désirées avec la touche 'CR' ou 'RETURN'. Et l'on termine la saisie avec un 'CTRL+D'.




 3.1 : EXECUTION COMMANDES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

A partir du SHELL interactif, une commande ou un programme exécutable se lance en composant sous le prompt '$' (ou '#' si l'on se trouve sous l'identité 'super-utilisateur') :

    ┌─────────────────────────────────────────────────────────────────┐
    │ Le nom de la commande ou du programme désiré                    │
    │ La ou les options éventuelles                                   │
    │ Le ou les arguments d'appel éventuels                           │
    │ La ou les redirection(s) d'entrée/sortie                        │
    │ Le caractère '&' si l'exécution doit se faire en arrière plan   │
    └─────────────────────────────────────────────────────────────────┘
                                  ┌───────────┐           ┌───────────┐
       Appel de commande simple : │ appel_cde │     ::=   │  nom_cde  │
                                  └───────────┘           └───────────┘
                                  ┌───────────┐           ┌─────────────────────────────────────────────────────────────────────────────────┐
       Appel de commande          │ appel_cde │     ::=   │  [var=valeur ...] nom_cde  [-opt1 [-opt2]...] [arg1 [arg2]...]  [redirect] [&]  │
                                  └───────────┘           └─────────────────────────────────────────────────────────────────────────────────┘

Une commande est une suite de mots dont le premier est considéré comme la commande à exécuter.

Les commandes sont soit des commandes internes du SHELL, des programmes exécutables ou des FONCTIONS SHELL définies par l'utilisateur.

La commande 'type' suivi du nom de commande à rechercher retourne :

 ┌────────────────────────────────────────┐
 │type cd  ::=  cd is a shell builtin     │(Commande interne)
 │                                        │
 │type cp  ::=  cp is /usr/bin/cp         │(Programme exécutable)
 │                                        │
 │type ls  ::=  ls is hashed (/usr/bin/ls)│(Programme exécutable) localisé dans la table système 'hash'.
 └────────────────────────────────────────┘

 ┌───────────────────────────────┐
 │type fct ::=  fct is a function│         (Fonction pré-définie)
 │              fct () {         │
 │              ......           │
 │              }                │
 └───────────────────────────────┘

Une commande (devant correspondre à un exécutable), spécifiée sans aucun '/' dans son nom, sera recherchée dans le ou les répertoires contenus dans la variable d'environnement 'PATH' examinée de la gauche vers la droite. De plus pour éviter cette recherche à chaque appel, une table système 'hash', liée au SHELL courant, contient la liste des localisations des commandes trouvées à partir du 'PATH' et permet un accès direct lors des appels ultérieurs.(Voir 'hash' et le chapitre 'ETAPES EXECUTION COMMANDE')

Si $PATH contient '/usr/bin:/opt/bin' alors le programme exécutable sera recherché d'abord dans '/usr/bin' puis dans '/opt/bin'.

Pour connaître la localisation d'un programme exécutable on peut utiliser la commande 'type' suivi du nom du programme.

  ┌──────────┐         ┌─────────────────────┐
  │ type cat │ affiche │ cat is /usr/bin/cat │
  └──────────┘         └─────────────────────┘

car le programme 'cat' a été trouvé à partir de $PATH dans '/usr/bin'.

Après une utilisation réelle de 'cat' la même commande
  ┌──────────┐         ┌─────────────────────────────┐
  │ type cat │ affiche │ cat is hashed (usr/bin/cat) │
  └──────────┘         └─────────────────────────────┘

qui indique que désormais la commande 'cat' est mémorisée dans la table 'hash' et que le système n'a plus à utiliser PATH.

Les options sont par convention distinguées des arguments par le préfixe '-' mais en fait elles sont traitées par le SHELL et reçues par le programme comme des arguments.

(Voir le chapitre 'NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS'

Chaque option ou argument est séparé des précédents par un ou plusieurs espaces.

Une commande SHELL peut contenir le nom de la commande, les options et les arguments spécifiés de façon explicite, ou en utilisant :

- Des variables d'environnement '$...' que le SHELL remplacera par leurs contenus (voir VARIABLES D'ENVIRONNEMENT).

- Des chaînes contenant des méta-caractères (*,!,[...],[!...]) dont le contenu sera modifié par le SHELL en générant des noms de fichiers à la place de ces chaînes en fonction des méta-caractères utilisés (voir META-CARACTERES NOMS FICHIERS).

A chaque appel de commande le SHELL interprète les noms de variables d'environnement ainsi que les méta-caractères avant d'exécuter la commande proprement dite.

La redirection des fichiers standard d'entrée/sortie se fait par la spécification de cette redirection avec les caractères '<', '>' ou ">>" ou encore "2>" ou "2>>" (Voir chapitre REDIRECTION).

              ┌───────────────┐
    Exemple : │ ls >/tmp/toto │  ::= Redirection de l'affichage dans un
              └───────────────┘        fichier '/tmp/toto'

On aura aussi la possibilité de synchroniser deux processus en reliant le fichier de sortie de l'un avec le fichier d'entrée de l'autre par le biais d'un '|' appelé 'pipe'.

            ┌──────────┐         ┌───────────────┐
            │ ls | lp  │   ::=   │ ls >/tmp/toto │
            └──────────┘         │ lp /tmp/toto  │
                                 └───────────────┘

Déjà on voit que certains caractères comme '<' '>' ou '|' sont interprétés par le SHELL comme des caractères spéciaux. Il en existe beaucoup d'autres qui font l'objet du chapitre suivant.

NIVEAUX 1 ET 2 DE SHELL

Lors de l'accès au SHELL, celui-ci affiche un texte (prompt) contenu dans 'PS1' ('#', si l'on est connecté comme 'super-utilisateur' et '$' si l'on n'est pas connecté comme 'super-utilisateur') et lors de la saisie et validation normale d'une commande simple on reste au niveau 1.

Si une commande est syntaxiquement incomplète, alors le SHELL passe au niveau 2 avec affichage du texte de niveau 2 contenu dans $PS2 (généralement un '>') pour la saisie interactive de la suite de la commande.

Ceci sera vrai lors de l'oubli de fermeture de chaînes encadrées par des «"» ou des «'» ou des commandes complexes comme 'if .... ' ou 'while ....'. Si un utilisateur valide une commande 'echo "abcd' où il n'y a pas fermeture de la chaîne encadrée par «"», le SHELL passera au niveau 2 et attendra la fermeture, exemple :

        ┌─────────────────────┐
        │ $ echo "abcd        │ Dans ce cas le texte 'abcd' sera séparé du
        │ > efgh"             │ texte 'efgh' par un passage à la ligne.
        └─────────────────────┘

Lors de l'apparition du texte $PS2 de niveau 2, on peut interrompre la saisie d'une commande erronée avec 'CTRL+C' et le SHELL revient au niveau 1.

  ┌──────────────┐
  │ $ while true │  Dans ce cas la commande 'while' attend une commande
  │ > do         │    conditionnant ce 'while' et un bloc 'do ... done'.
  │ > ls -la *   │  La composition de la commande 'while' seule entraîne
  │ > done       │    le passage au niveau 2 et ce n'est que lorsque le
  └──────────────┘    'done' aura été composé que la totalité de la commande sera traitée. La syntaxe de 'while' sera vérifié de façon interactive.

FICHIER STANDARD D'ENTREE

Certaines commande (cat, sort, etc...) travaillent par défaut avec le fichier standard d'entrée. Ceci veut dire qu'en absence de nom de fichier à traiter, ces commandes attendent des données sur le fichier standard d'entrée. Celui-ci par défaut est constitué du clavier du terminal.

Donc si l'on exécute une commande comme 'cat' sans spécifier de nom de fichier à traiter, alors la commande attend des données sur le clavier.

L'opérateur saisit alors la ou les lignes désirées et devra, en fin de traitement, composer un 'EOF' ('CTRL+D') pour indiquer la fin de la la saisie.

    ┌─────────┐
    │ $ cat   │
    │ abcd    │ Chaque ligne validée par 'CR' (RETURN) est affichée au fur
    │ abcd    │ et à mesure.  (Les lignes affichées sont représentées en
    │ efgh    │ caractères gras).
    │ efgh    │
    │ CTRL+D  │
    │ $       │
    └─────────┘

    ┌─────────┐
    │ $ sort  │             ┌──────┐
    │ toto    │             │ titi │
    │ titi    │   Affichera │ toto │ après la saisie du 'CTRL+D'
    │ tutu    │             │ tutu │ L'affichage se fait en fin de saisie
    │ CTRL+D  │             └──────┘ car 'sort' doit attendre la dernière
    │ $       │                      ligne pour terminer le tri.  Mais les
    └─────────┘                      lignes ont été lues au fur et à mesure.




 3.1.1 : CARACTERES SPECIAUX DU SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Comme vu précédemment il existe pour l'appel d'une commande des caractères spéciaux :

Il est important de noter que tous ces caractères sont interprétés par le SHELL avant exécution. Si on utilise un tel caractère sans le marquer (\) ou l'encadrer, le résultat peut être surprenant.

Exemple : On utilise couramment l'instruction 'wget URL' mais un beau jour avec une URL contenant des caractères spéciaux la commande ne fonctionne pas comme on le voudrait. Ce n'est pas la faute du SHELL mais de l'utilisateur qui n'a pas utilisé de quotes ou de doubles quotes.

  ┌──────────────────────────────────────┐
  │ wget http://url?arg1=val1&arg2=val2  │ 
  └──────────────────────────────────────┘

Dans ce cas, le shell interprète le '?' (peu de chances d'avoir un fichier correspondant à 'http://urlxarg...') mais surtout le '&'.

Il coupe donc la commande en deux et envoie la première partie en arrière plan et essaye d'exécuter la deuxième.

     ┌───────────────────────────┬─────────────────────────────────┐
     │  Espace ou tabulation     │ Séparateur de mots (arguments)  │
     │            horizontale    │                                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  # commentaire            │ Caractère de commentaire        │
     │                           │                                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  :                        │ Commande vide                   │
     │                           │                                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  ;  commande_suite        │ Séparateur de commandes         │
     │  && commande_suite        │ définies sur la même ligne.     │
     │  || commande_suite        │                                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  ~                        │ Caractère ~ lié à la HOME       │
     │                           │ de l'utilisateur ou d'un        │
     │                           │ autre utilisateur.              │
     ├───────────────────────────┼─────────────────────────────────┤
     │  &                        │ Exécution de la commande en     │
     │                           │ arrière plan.                   │
     ├───────────────────────────┼─────────────────────────────────┤
     │  < , > , 2> , >> , 2>> ,  │ Caractères de redirection       │
     │  <<mot  , <<-mot          │ des entrées/sorties standard.   │
     │  coucou1                  │ Voir chapitre REDIRECTION.      │
     ├───────────────────────────┼─────────────────────────────────┤
     │  | (pipe)                 │ Mise en communication de la     │
     │                           │ sortie standard d'un processus  │
     │                           │ avec l'entrée d'un autre proces-│
     │                           │ sus.                            │
     ├───────────────────────────┼─────────────────────────────────┤
     │  $ avec éventuellement {} │ Contenu de variable             │
     │                           │ d'environnement                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  \x                       │ Marquage d'un caractère spécial │
     │                           │ 'x' à ne pas interpréter        │
     ├───────────────────────────┼─────────────────────────────────┤
     │  \ en fin de ligne        │ Caractère de continuation de    │
     │                           │ la commande sur la ligne        │
     │                           │ suivante.                       │
     ├───────────────────────────┼─────────────────────────────────┤
     │  * , ? , [...] , [!...]   │ Méta-caractères (joker) pour la │
     │                           │ génération de noms de fichiers. │
     ├───────────────────────────┼─────────────────────────────────┤
     │  "......"                 │ Encadrement de chaîne avec      │
     │                           │ interprétation partielle.       │
     ├───────────────────────────┼─────────────────────────────────┤
     │  '......'                 │ Encadrement de chaîne sans      │
     │                           │ interprétation.                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  {......}                 │ Expansion des accolades         │
     │                           │ listes ou expansion de noms     │
     │                           │ de fichiers                     │
     ├───────────────────────────┼─────────────────────────────────┤
     ├───────────────────────────┼─────────────────────────────────┤
     │  `cde arg`                │ Encadrement d'une commande à    │
     │                           │ exécuter et dont on récupère    │
     │   voir aussi $(cde arg)   │ l'affichage du résultat.        │
     │                           │                                 │
     ├───────────────────────────┼─────────────────────────────────┤
     │  ( cde1 ; cde2 ... ) .... │ Regroupement de plusieurs cdes  │
     │                           │ en un seul bloc logique qui sera│
     │                           │ interprété avant d'interpréter  │
     │                           │ ce qui suit.                    │
     ├───────────────────────────┼─────────────────────────────────┤
     │ =                         │ Le caractère '=' séparant sans  │
     │ nom_var=valeur            │ espace deux chaînes permet      │
     │ nom_var=valeur nom_cde    │ l'initialisation ou la          │
     │                           │ la modification d'une variable  │
     │                           │ SHELL. Voir le chapitre         │
     │                           │ 'VARIABLES D'ENVIRONNEMENT')    │
     │                           │ Séparé d'un nom par au moins un │
     │                           │ espace le '=' est traité comme  │
     │                           │ un caractère quelconque.        │
     ├───────────────────────────┼─────────────────────────────────┤
     │ . nom_script              │ Un '.' suivi d'un nom de script │
     │                           │ indique que ce script doit être │
     │                           │ interprété dans le processus    │
     │                           │ courant.                        │
     │                           │ (Voir chapitre 'EXECUTION D'UN  │
     │                           │ SCRIPT).                        │
     │                           │ Placé à un autre endroit dans   │
     │                           │ une commande, ce caractère est  │
     │                           │ traité comme un caractère       │
     │                           │ quelconque.                     │
     └───────────────────────────┴─────────────────────────────────┘




 3.1.1.1 : ESPACE ou TABULATION ENTRES ARGUMENTS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

L'espace ou tabulation : un seul espace ou plusieurs espaces consécutifs ou une ou plusieurs tabulations consécutives sont considérés comme un seul séparateur. (Voir chapitre sur l'appel d'une commande).




 3.1.1.2 : '#' SEPARATEUR MARQUANT UN COMMENTAIRE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le '#' est interprété comme caractère de commentaire. Tout ce qui suit jusque la fin de la ligne est considéré comme commentaire (à condition que le '#' soit isolé à gauche par un ou plusieurs espace(s) ou tabulation(s)).

      ┌───────────────────────────┐              ┌───────────┐
      │ echo  abcdefgh # ijklmnop │  Affichera : │ abcdefgh  │
      │ echo  toto # titi         │  Affichera : │ toto      │
      │ echo  toto #titi          │  Affichera : │ toto      │
      │ echo  toto#titi           │  Affichera : │ toto#titi │
      └───────────────────────────┘              └───────────┘




 3.1.1.3 : ';' "&&" "||" CDES EXECUTEES EN SEQUENCE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Les trois caractères ou couples de caractères ';' '&&' ou '||' permettent de définir plusieurs commandes dans la même ligne.

Sur la même ligne on peut avoir plusieurs commandes séparées par un ';' ou par "&&" ou encore "||" :

Exemple d'appel de commande multiple :

      ┌────────────────────────────────┐
      │appel_cde1 ; appel_cde2 ....... │
      └────────────────────────────────┘

      ┌─────────────┐
      │ cde1 ; cde2 │
      └─────────────┘

Dans le cas d'appel multiple avec ';' la commande 'cde2' sera exécutée quelque soit le code de retour de la commande précédente.

      ┌──────────────┐
      │ cde1 && cde2 │
      └──────────────┘

La commande de droite ne sera exécutée que si la commande de gauche a retourné une valeur égale à 0 (Sortie normale).

      ┌──────────────┐
      │ cde1 || cde2 │
      └──────────────┘

La commande de droite ne sera exécutée que si la commande de gauche a retourné une valeur différente de 0 (Sortie anormale).

Le ';' a la priorité la plus basse et '&&' ou '||' ont une priorité identique.

ATTENTION : Il ne faut pas confondre cette utilisation séquentielle de commandes avec le 'pipe' (Voir plus loin) qui est une utilisation en parallèle de deux commandes.

ATTENTION : Une redirection d'entrée/sortie, même sur la dernière commande, n'affecte que la commande concernée et non l'ensemble des commandes. Si l'on désire réaliser plusieurs commandes dans une seule et même redirection, alors il faudra encadrer les commandes avec des "()" (Voir le chapitre BLOC DE COMMANDES)

CODE DE RETOUR
  ┌──────────────────────────────────────────────────────────────┐
  │ Le code de retour est celui de la dernière commande exécutée │
  └──────────────────────────────────────────────────────────────┘




 3.1.1.4 : '~' Expansion du tilde   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

???.

Le caractère '~' (tilde) servira à identifier le répertoire HOME de l'utilisateur courant ou d'un autre utilisateur spécifié par son 'login'.

Mais il pourra aussi servir à naviguer d'un répertoire à l'autre ou dans la pile des répertoires où on s'est déjà positionné.

Si un mot commence avec le caractère tilde (« ~ »), tous les caractères précédant le premier slash non protégé (voire tous les caractères s'il n'y a pas de slash), sont considérés comme un préfixe tilde.

Si aucun caractère du préfixe tilde n'est protégé, les caractères suivant le tilde sont traités comme un nom de login possible.

Si ce nom de login est une chaîne nulle, le tilde est remplacé par la valeur de la variable HOME.

Si HOME n'existe pas, le tilde est remplacé par le répertoire de connexion de l'utilisateur exécutant le shell.

Si le préfixe tilde est remplacé par le répertoire personnel associé au nom de login en question.

Si le préfixe tilde est « + », la valeur de la variable shell PWD le remplace.

Si le préfixe tilde est « - », la valeur de la variable shell OLDPWD lui est substitué.

Si les caractères à la suite du tilde dans le préfixe tilde représentent un nombre N préfixé éventuellement d'un « + » ou d'un « - » le préfixe tilde est remplacé par l'élément correspondant de la pile de répertoires telle qu'il serait affiché par la commande interne dirs invoquée avec le préfixe tilde en argument.

Si les caractères à la suite du tilde dans le préfixe tilde représentent un nombre sans signe, on suppose qu'il s'agit de « + ».

Si le nom est invalide, ou si le développement du tilde échoue, le mot est inchangé.

Chaque affectation de variable est soumis au développement du tilde s'il suit immédiatement un : ou le premier =. On peut donc utiliser des chemins d'accès avec un tilde pour remplir les variables PATH MAILPATH et CDPATH et le shell fournira la valeur correcte.




 3.1.1.5 : '&' EXECUTION EN ARRIERE PLAN   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Une commande se terminant par un '&' sera exécutée par le SHELL mais en arrière plan. C'est à dire que l'on récupère la main tout de suite sur l'écran et que la commande se déroule en parallèle de l'activité que l'on pourra avoir sur le terminal (Tâche envoyée en 'fantôme').

Au lancement de l'exécution en arrière plan le SHELL affiche sur la sortie standard le numéro de processus correspondant à la tâche .

Ce numéro pourra être traité ensuite par la commande 'wait' (voir la commande 'wait')

Par défaut le fichier d'entrée d'une commande exécutée en arrière plan est '/dev/null' et sera donc toujours considéré comme vide.

ATTENTION : Si la sortie standard et ou erreur d'une commande envoyée en arrière plan n'est pas redirigée dans un fichier, alors par défaut cette commande travaille avec la sortie standard et la sortie d'erreur standard et il risque d'y avoir à l'écran un mélange des affichages des commandes envoyées en arrière plan et de celles que l'on exécute en même temps sur le terminal.

ATTENTION : Les commandes envoyées en arrière plan sont soumises à l'environnement courant. S'il reste des commandes lancées en arrière plan lors de la dé-connexion du poste ou lors d'une coupure de ligne de ce poste, ces commandes peuvent être interrompues en fonction du positionnement du 'trap 1' ('HANGUP').

Voir la commande 'trap' pour ignorer cette interruption ou voir la commande 'nohup' pour lancer une commande en étant sûr qu'elle ne soit pas interrompue.(Exemple : 'nohup cde ..... &') Pour lancer une commande en arrière plan avec une priorité faible, voir aussi la commande 'nice' (Exemple : 'nice cde .... &').




 3.1.1.6 : '<' '>' '>>' '<<' CARACT. REDIRECTION E/S   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Les caractères '<', '>' ou '|' sont interprétés comme spécifiant des redirections d'entrée/sortie.

Le '|' sera vu dans le chapitre suivant.

En standard un processus possède trois fichiers identifiés par les numéros 0, 1 et 2 :

        ┌─────────────────────────────────────────────────────────────┐
        │ 0  ::=  Fichier d'entrée standard (Par défaut le clavier).  │
        │ 1  ::=  Fichier de sortie standard (Par défaut l'écran).    │
        │ 2  ::=  Fichier de sortie des erreurs (Par défaut l'écran). │
        └─────────────────────────────────────────────────────────────┘

Les valeurs 0 et 1 sont symbolisées par l'utilisation du caractère '<' ou '>' bien que l'on puisse aussi utiliser '0<' ou '1>'.

Redirection du fichier d'entrée
      ┌─────────────────┐
      │ <nom_fic_entrée │ ::= Pour lire des données dans un fichier au lieu
      └─────────────────┘       de les attendre du clavier.

Redirection dans un fichier à créer ou à recréer
      ┌─────────────────┐
      │ >nom_fic_sortie │ ::=  Pour rediriger l'affichage de sortie dans le fichier spécifié au lieu d'un affichage à
      └─────────────────┘        l'écran. Ce fichier sera créé ou recréé s'il existait déjà.

                  ┌──────────────────┐
        Exemple : │ ls -la y*  >toto │ ::= Redirige le résultat de la
                  └──────────────────┘     commande 'ls' dans le fichier "toto".

     ┌──────────────────┐
     │ 2>nom_fic_erreur │ ::=  Pour rediriger l'affichage de sortie des erreurs dans le fichier spécifié au lieu
     └──────────────────┘        d'un affichage à l'écran.  Ce fichier sera créé ou recréé s'il existait déjà.

                   ┌────────────────────┐
         Exemple : │ ls -la y* 2>erreur │  ::= Redirige le message
                   └────────────────────┘        d'erreur éventuel dans le fichier "erreur"

                   ┌───────┐
                   │ >toto │               ::= Création d'un fichier vide appelé "toto"
                   └───────┘  

Redirection à la suite d'un fichier éventuellement existant
     ┌──────────────────┐
     │ >>nom_fic_sortie │ ::=  Pour rediriger l'affichage de sortie à la suite du fichier spécifié au lieu d'un affichage à l'écran.
     └──────────────────┘      Ce fichier sera créé s'il n'existe pas déjà.

     ┌───────────────────┐
     │ 2>>nom_fic_erreur │ ::=  Pour rediriger l'affichage des messages d'erreur à la suite du fichier spécifié au
     └───────────────────┘        lieu d'un affichage à l'écran.  Ce fichier sera créé s'il n'existe pas déjà.

Fermeture d'une redirection

<&- ::= Fermeture du fichier d'entrée >&- ::= Fermeture du fichier de sortie standard 2>&- ::= Fermeture du fichier de sortie d'erreur

Dans le cas d'une fermeture en entrée on considère avoir atteint la fin de fichier.

Dans le cas d'une fermeture en sortie les affichages sont perdus comme avec une redirection sur '/dev/null'.

Dans un script SHELL ces fonctions n'ont de sens qu'avec 'exec' afin de forcer le SHELL à exécuter ces commandes dans le processus en cours.

Un changement de redirection pendant le déroulement d'un processus se fait avec la commande 'exec' sans spécification de commande exécutable mais avec uniquement la ou les redirections désirées (Voir 'exec').

Redirection en utilisant des numéros de fichiers standard

<&x ou >&x : Associe le fichier x (0, 1 ou 2) comme redirection.

     ┌───────────────────┐
     │ ls -la >toto 2>&1 │ ::= Sortie standard sur 'toto' et sortie d'erreur dans le même fichier qui contiendra un
     └───────────────────┘       mélange chronologique des affichages standard et des erreurs.

     ┌────────────────────────┐
     │ echo "Erreur ...." >&2 │ ::= La commande 'echo' affiche toujours sur la sortie standard mais l'on peut
     └────────────────────────┘       avec '>&2' re-diriger cette sortie sur la sortie d'erreur.

Comme 'echo' est une commande interne cette redirection se fait avec les entrées/sorties du SHELL courant.

Redirection conditionnelle sur la valeur d'un mot

<<mot ou <<-mot : Après substitution éventuelle de 'mot' l'entrée du SHELL est lue jusqu'à la rencontre de ce mot ou jusque la fin du fichier.

Si le caractère '-' est utilisé, alors :

- Les tabulations sont supprimées du mot spécifié - Les tabulations sont supprimées des entrées du SHELL avant que 'mot' soit rencontré ou avant la fin du fichier.

Exemple : cat <<fin >toto Cette commande recopiera tout ce que l'on compose à l'écran dans le fichier "toto" jusqu'à ce que l'on compose "fin" et ce "fin" ne sera pas présent dans le fichier résultat "toto".

Il est à noter qu'à l'écran le SHELL affiche un '>' indiquant que l'on se trouve au niveau 2 du SHELL (saisie de données complémentaires).

Cette fonctionnalité n'est pas très utile dans une saisie de commande composée à l'écran (l'exemple précédent aurait pu être remplacé par un 'cat >toto' suivi de la saisie du texte et un 'CTRL+D' au lieu de composer 'fin'). Mais lors de l'écriture de scripts SHELL, elle sera très commode en combinaison avec des commandes qui lisent des données l'entrée standard.

Exemple : La commande 'mail' permet d'envoyer un message, dans la boite aux lettres d'un destinataire, mais lit ce message sur l'entrée standard.

   ┌ Saisie écran  ┐  ┌─ Saisie écran   ───┐  ┌─ Exemple script ─────────┐
   │  $ mail root  │  │  $ mail root <<fin │  │  mail root <<fin         │
   │  ligne 1      │  │  > ligne 1         │  │  ligne 1                 │
   │  ligne 2      │  │  > ligne 2         │  │  ligne 2                 │
   │  ligne n      │  │  > ligne n         │  │  ligne n                 │
   │  CTRL+D       │  │  > fin             │  │  fin                     │
   │  $            │  │  $                 │  │  ..... (suite du script) │
   └───────────────┘  └────────────────────┘  └──────────────────────────┘

ATTENTION : La redirection de sortie standard ou d'erreur est interprétée par le SHELL avant exécution réelle de la commande et donc le ou les fichier(s) utilisé(s) en redirection sont d'abord construits ou reconstruits avant exécution.

Exemple : 'ls -l toto >toto' commence par créer "toto" avant d'en faire une liste qui contiendra les caractéristiques d'un fichier vide et non celles du fichier "toto" avant la validation de la commande.

ATTENTION : Les méta-caractères (Voir chapitre META-CARACTERES) ne sont pas interprétés par le SHELL lorsqu'ils sont utilisés dans des chaînes de caractères utilisées pour des redirections (Sauf dans le cas de "<<mot").

Exemple : ls >toto* ::= Redirection de l'affichage dans un fichier 'toto*'.

ATTENTION : L'ordre des redirections est IMPORTANT car le SHELL les examine de la gauche vers la droite
            ┌──────────────────────┐
            │ ...... >toto    2>&1 │     ::= Associe à la sortie d'erreur
            └──────────────────────┘           le même fichier que la sortie

standard donc "toto".

n'aura pas la même signification que
             ┌───────────────────────┐
             │..... 2>&1       >toto │   ::= Associe à la sortie d'erreur
             └───────────────────────┘         la sortie standard et ensuite

redirige la sortie standard sur "toto".

Si une commande est constituée de plusieurs commandes simples, alors le SHELL évalue les redirections de l'ensemble de la commande avant d'examiner les redirections éventuelles de chaque commande simple.




 3.1.1.7 : '|' COMMUNICATION PROCESSUS PAR PIPE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Pour faire communiquer le fichier de sortie d'un processus avec le fichier d'entrée d'un autre processus on utilise le mécanisme de 'pipe' avec le caractère '|' :

       ┌───────────────────────────────────────────────────────────┐
       │ cde1 [-options] [arguments] | cde2 [-options] [arguments] │
       └───────────────────────────────────────────────────────────┘

Cette commande est équivalente à :

       ┌────────────────────────────────────┐
       │ cde1 [-options] [arguments] >toto  │
       │            suivie de :             │
       │ cde2 [-options] [arguments] <toto  │
       └────────────────────────────────────┘

Mais dans le cas du 'pipe' on ne passe pas par un fichier de manoeuvre et c'est le SHELL qui synchronise les données émises par la première commande et celles reçues par la deuxième.

Ne pas confondre le mécanisme de 'pipe' qui déroule en parallèle deux commandes avec l'appel de deux commandes séparées par un ';' car dans le cas du ";" la deuxième commande n'est exécutée qu'à la fin de la première (et selon son code de retour) et donc sans communication entre chaque commande.

L'expéditeur envoie ses données dans le 'pipe' et si le bloc tampon est plein, il se met en attente de façon à permettre au destinataire de traiter les informations reçues, ce qui vide le bloc tampon et permet au destinataire de continuer à envoyer des données. Lorsque l'expéditeur a terminé son travail il envoie un signal de fin de fichier qui indique au destinataire qu'il n'y a plus rien à recevoir. Le destinataire finit son traitement et lorsque celui-ci sera terminé, les deux processus seront effacés.

(Pour plus de détails voir 'DETAILS SUR L'EXECUTION DES PROCESSUS').

CODE DE RETOUR
  ┌───────────────────────────────────────────────────┐
  │ Le code de retour est celui de la commande finale │
  └───────────────────────────────────────────────────┘




 3.1.1.8 : '$' CONTENU D'UNE VARIABLE D'ENVIRONNEMENT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le SHELL gère des variables d'environnement qui vont permettre de manipuler des valeurs contenues dans ces variables. Mais contrairement à des langages où les variables sont examinées du point de vue syntaxique comme des éléments, le SHELL substitue chaque appel de variable par sa valeur avant exécution de la ligne de commande.

Au cas où une variable n'est pas définie il n'y a pas d'erreur spécifiée mais un remplacement par une chaîne vide (Sauf avec l'option '-u' du SHELL, voir 'set', et dans ce cas l'utilisation d'une variable non définie entraîne une erreur)

Une variable est spécifiée par un nom et le contenu de cette variable est spécifié par le caractère '$' suivi du nom de variable.

Si la variable 'fic' contient "toto" alors on peut utiliser une
    commande : ┌──────────┐       ┌──────────┐
               │ cat $fic │  ::=  │ cat toto │
               └──────────┘       └──────────┘

Par la suite, une modification du contenu de 'fic' permettra de faire varier le fonctionnement de 'cat $fic'.

Si une variable 'cde' contient la chaîne "cat" et la variable 'fic' contient "toto" on peut utiliser une commande :

            ┌───────────┐       ┌──────────┐
            │ $cde $fic │  ::=  │ cat toto │
            └───────────┘       └──────────┘

Dans un langage traditionnel l'utilisation d'une variable ne peut pas se faire pour spécifier une instruction, mais avec le mécanisme de substitution du SHELL, tout est possible...

La syntaxe est très libre et le nom d'une variable peut très bien être précédé ou suivi d'autres caractères mais dans certain cas il faudra utiliser les caractères '{' et '}' pour encadrer le nom de la variable sans ambiguïté (Pour plus de détail, voir le chapitre 'VARIABLES D'ENVIRONNEMENT).

                   ┌───────────────┐           ┌──────────────────────────┐
        Exemple :  │ echo $TERM    │ affiche : │ xterm                    │
                   └───────────────┘           └──────────────────────────┘

                   ┌───────────────┐           ┌──────────────────────────┐
                   │ echo A$TERM   │ affiche : │ Axterm                   │
                   └───────────────┘           └──────────────────────────┘
                   ┌───────────────┐           ┌──────────────────────────┐
                   │ echo $TERMB   │ affiche : │ Une chaîne vide si la    │
                   └───────────────┘           │ variable TERMB n'est pas │
                                               │ définie.                 │
                                               └──────────────────────────┘

                   ┌───────────────┐           ┌──────────────────────────┐
                   │ echo ${TERM}B │ affiche : │ xtermB                   │
                   └───────────────┘           └──────────────────────────┘

La substitution se fait par défaut au premier niveau mais la commande 'eval' permet de faire des substitutions en cascade :

Si $x contient '$y' et que $y contient 'coucou'
          ┌──────────────┐           ┌────────┐
          │ echo $x      │ Affiche   │ $y     │
          └──────────────┘           └────────┘

          ┌──────────────┐           ┌────────┐
          │ eval echo $x │ Affiche   │ coucou │
          └──────────────┘           └────────┘




 3.1.1.9 : CARACTERE '\' ('backslash')   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le caractère '\' sert à marquer le caractère qui suit afin que celui-ci ne soit pas interprété directement par le SHELL.

              ┌──────────┐  ┌────────────────────────────────────────┐
              │ echo a;b │  │ Affichera : a                          │
              └──────────┘  │ et essaiera d'exécuter la commande 'b' │
                            └────────────────────────────────────────┘

               ┌──────────┐ ┌─────────────────┐
               │echo a\;b │ │ Affichera : a;b │
               └──────────┘ └─────────────────┘

Lorsque l'on voudra vraiment un '\' on le masquera par un '\' et donc :

             ┌───────────┐  ┌─────────────────┐
             │ echo a\\b │  │ Affichera : a\b │
             └───────────┘  └─────────────────┘

Le '\' en fin de ligne sera interprété par le SHELL comme un caractère de continuation à la ligne suivante. En effet on ignore le caractère qui suit donc on ignore le caractère 'LF' de retour à la ligne, donc on ignore le passage à la ligne suivante.

Lors de l'interprétation de la ligne de commande par le SHELL la suite de deux '\' consécutifs est transformée en un seul '\'.

Et le ou les caractères qui suivent sont envoyés à la commande.

Dans une chaîne encadrée par des «"» il n'est pas nécessaire d'utiliser deux '\' consécutifs et un seul suffira.

(Voir le chapitre ENCADREMENT DE CHAINES)

Derrière la suite \\x ou dans une chaîne "\x" on pourra spécifier et pour certaines commandes ('echo', 'tr', ...) :

Des valeurs octales Des caractères spéciaux

VALEURS OCTALES

Les deux caractères "\0" (obtenus avec \\0) permettent d'introduire des caractères avec leur valeur octale :

A noter que la valeur octale peut être sur 1, 2 ou 3 caractères mais que si l'on désire lever une ambiguïté avec les caractères qui suivent il EST IMPERATIF de cadrer la valeur sur 3 caractères avec des '0' à à gauche.

 echo -e \\041   ::= echo -e "\041"  : Affiche un '!' ('!' = 041 en octal)
 echo -e \\0101  ::= echo -e "\0101" : Affiche un 'A' ('A' = 101 en octal)
 echo -e \\07    ::= echo -e "\07"   : Fait sonner le terminal.('BEL'=7 en octal)
 echo -e \\071   ::= echo -e "\071"  : Affiche un '9' ('9' = 071 en octal)
 echo -e \\00071 ::= echo -e "\00071": Affiche une sonnette et le caractère 1

Il est important de noter que l'interprétation du ou des caractères qui suivent le '\' sera faite par la commande elle même et pas par le SHELL.

Des commandes comme 'echo' assurent cette interprétation mais certaines commandes comme 'grep' ne l'assurent pas. Exemple :

 ┌─────────────────┐
 │ grep "\07" toto │      ::= Ne permet pas de chercher les lignes contenant une sonnette mais des lignes contenant '07'.
 └─────────────────┘ 

 ┌───────────────────────────┐
 │ grep `echo -e "\07"` toto │ ::= En passant par un `echo ...` on pourra demander cette recherche
 └───────────────────────────┘       à 'grep' (Voir le chapitre 'ENCADREMENT DE COMMANDES')

 ┌───────────────┐
 │ SONNETTE=\\07 │ ::= Permet d'initialiser la variable 'SONNETTE' avec la chaîne '\07' qui pourra être utilisée dans une
 └───────────────┘       commande 'echo -e $SONNETTE' mais pas directement dans une commande 'grep'.

 ┌───────────────────────────┐
 │ SONNETTE=`echo -e  "\07"` │ ::= Permet d'initialiser la variable 'SONNETTE' avec la valeur octale '07' et donc vraiment 
 └───────────────────────────┘       le caractère correspondant à la sonnette du terminal.

CARACTERES DE CONTROLE Pour éviter d'utiliser systématiquement des valeurs octales il existe un certain nombre de caractères de contrôle ASCII qui seront reconnus par certaines commandes (echo, tr, etc...) :

       ┌──────────────────────────────────────────────────────────┐
       │  \b   BS   Retour en arrière d'un caractère              │
       │  \c        Suppression du 'LF' (fin de ligne) implicite  │
       │  \f   FF   Saut de page                                  │
       │  \n   LF   Passage à la ligne suivante                   │
       │  \r   CR   Retour en début de ligne                      │
       │  \t   TAB  Tabulation horizontale                        │
       │  \v   VTAB Tabulation verticale                          │
       └──────────────────────────────────────────────────────────┘

             ┌────────────────────────┐                ┌────────┐
   Exemple : │ echo -e ABCDEF\\nGHIJK │  affichera  :  │ ABCDEF │
             └────────────────────────┘                │ GHIJK  │
                                                       └────────┘

             ┌─────────────────────────┐               ┌────────┐
             │ echo -e "ABCDEF\nGHIJK" │ affichera  :  │ ABCDEF │
             └─────────────────────────┘               │ GHIJK  │
                                                       └────────┘

En cas d'utilisation de «"» ou «'» le '\' n'a pas besoin d'être doublé (Voir le chapitre 'ENCADREMENT DE CHAINES').

Exemple d'écriture en deux instructions sans passage à la ligne :

       ┌───────────────────────────┐         ┌──────────────────────────┐
       │ echo -e "abcdef\c" >toto  │    ::=  │ echo "abcdefghijk" >toto │
       │ echo    "ghijk"    >>toto │         └──────────────────────────┘
       └───────────────────────────┘

Même remarque pour l'interprétation des caractères de contrôle que pour les valeurs octales :

Il est important de noter que l'interprétation du caractère qui suit le '\' sera faite par la commande elle même et pas par le SHELL.

Des commandes comme 'echo' assurent cette interprétation mais certaines commandes comme 'grep' ne l'assurent pas. Exemple :

 ┌────────────────┐
 │ grep "\f" toto │      ::= Ne permet pas de chercher les lignes contenant
 └────────────────┘            un saut de page mais le caractère 'f'.

 ┌───────────────────────────┐
 │ grep `echo -e  "\f"` toto │ ::= En passant par un `echo ...` on pourra
 └───────────────────────────┘       demander cette recherche à 'grep' (Voir le chapitre 'ENCADREMENT DE COMMANDES')

 ┌──────────┐     Permet d'initialiser la variable 'SAUT' avec la chaîne
 │ SAUT=\\f │ ::=   "\f" et la variable 'SAUT' pourra être utilisée dans
 └──────────┘        une commande 'echo $SAUT' mais pas directement dans une commande 'grep'.

 ┌─────────────────────┐
 │ SAUT=`echo -e "\f"` │ ::= Permet d'initialiser la variable 'SAUT' avec la
 └─────────────────────┘       valeur octale '\014' et donc vraiment le caractère correspondant au saut de page.

En fait l'utilisation du '\' devant un caractère fait que le SHELL n'interprète pas ce caractère. Ainsi pour afficher 'abc' on peut utiliser indifféremment : echo abc ou echo \a\b\c

La présence, d'un ou plusieurs espace(s), étant considérée comme séparateur d'arguments, on pourra avoir des problèmes pour passer des arguments contenant des espaces.

echo a b c affichera : a b c echo a\ \ \ b\ \ \ c affichera : a b c

Pour résoudre le problème il sera possible aussi d'encadrer la chaîne contenant des espaces avec des «"» ou des «'» (Voir chapitre 'ENCADREMENT DE CHAINES')




 3.1.1.10 : '*', '?', '[]' META-CARACTERES NOMS FICHIERS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Afin de faciliter l'exploitation des noms de fichiers dans des répertoires, il existe plusieurs caractères spéciaux :

Ces caractères sont souvent appelés 'méta-caractères' ou 'joker'.

Si le SHELL rencontre de tels caractères dans les arguments d'appel de commande, il cherche à remplacer le ou les méta-caractères à partir des noms de fichiers contenus dans le répertoire courant ou du répertoire spécifié et qui satisfont à la sélection demandée :

Si l'argument contenant un ou plusieurs méta-caractères correspond à plusieurs noms de fichiers, ceux ci seront fournis par ordre alphabétique croissant.

  ┌───┐
  │ * │             désigne n'importe quelle chaîne de caractères même vide.
  └───┘             

  ┌───┐
  │ ? │             désigne n'importe quel caractère non vide.
  └───┘             

  ┌──────────┐
  │ [car...] │      Désigne une liste de caractères 
  └──────────┘

  ┌───────────────┐
  │ [car_d-car_f] │  Désigne une suite de caractères consécutifs comprise entre car_d et car_f. 
  └───────────────┘  On peut spécifier une ou plusieurs suites.

  ┌───────────┐     ┌───────────┐ 
  │ [^......] │ ou  │ [!......] │    Tous les caractères ne correspondant pas à la liste ou suite spécifiée.
  └───────────┘     └───────────┘

Les caractères '^', '!' et '-' ont uns signification précise en fonction de leur emplacement, mais si on les utilise à un autre endroit ils perdent leur signification.

  ┌────────────────────┐ 
  │ [[:classe_posix:]] │  Cette forme reprend les classes POSIX : alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
  └────────────────────┘ 

{chaine1,chaine2,...} Cette forme permet de spécifier des chaines de caractères.

Si l'option extglob du shell est activée par la commande shopt plusieurs opérateurs de correspondance étendue sont reconnus.

Dans la description suivante, une liste-motif est une liste d'un ou plusieurs motifs séparés par des |. i Les motifs composés sont formés en utilisant un ou plusieurs sous-motifs comme suit :

    ?(liste-motif)
        Correspond à zéro ou une occurrence des motifs indiqués 
    *(liste-motif)
        Correspond à zéro ou plusieurs occurrences des motifs indiqués 
    +(liste-motif)
        Correspond à une ou plusieurs occurrences des motifs indiqués 
    @(liste-motif)
        Correspond à une occurrence exactement des motifs indiqués 
    !(liste-motif)
        Correspond à tout sauf les motifs indiqués 

  ┌────────┐
  │ [ABCD] │        désigne soit 'A', 'B', 'C' ou 'D'.
  └────────┘

  ┌───────┐
  │ [A-Z] │          désigne tout caractère compris entre 'A' et 'Z'.
  └───────┘

  ┌─────────┐ ┌─────────┐
  │ [^ABCD] │ │ [!ABCD] │        désigne tout caractère différent de 'A', 'B', 'C' ou 'D'.
  └─────────┘ └─────────┘          
  ┌────────┐ ┌────────┐
  │ [^a-z] │ │ [!a-z] │          désigne tout caractère non compris entre 'a' et 'z'.
  └────────┘ └────────┘

  ┌────────┐   ┌──────────────┐
  │ *[0-9] │   │ *[[:digit:]] │  désigne tout fichier dont le nom se termine par un chiffre.
  └────────┘   └──────────────┘

ATTENTION : Ces caractères '*' ou '?' s'appliquent à tous les fichiers sauf ceux qui commencent par un '.'. Pour ces fichiers le '.' devra être spécifié de façon explicite.

Exemple : ls * ::= Affiche tous les fichiers sauf ceux qui commencent par un '.'.

echo .*::= Affiche tous les fichiers qui commencent par un '.'.

ls .* ::= Affiche tous les fichiers qui commencent par un '.'.

Mais comme 'ls' liste le contenu des répertoires donnés en arguments, cette commande listera aussi le contenu du répertoire '..' (père). Dans ce cas pour éviter cette liste il faudra utiliser la commande 'ls -d .*' ou 'ls -a' (Voir 'ls').

ls ?e* ::= Affiche tous les fichiers qui ont un 'e' en deuxième position sauf si le premier caractère est un '.'.

ls .e* ::= Affiche tous les fichiers qui commence par '.e'.

On peut bien sûr combiner plusieurs méta-caractères pour définir des critères de recherche complexes :

a* ::= Tout fichier commençant par 'a'

*.c ::= Tout fichier finissant par ".c" (sauf ceux commençant par un '.').

a*.c ::= Tout fichier commençant par 'a' et finissant par ".c".

[Aa]*.c ::= Tout fichier commençant par 'A' ou 'a' et finissant par ".c".

????.c ::= Tout fichier commençant par quatre caractères quelconques (sauf le '.'en 1ère position) et finissant par ".c".

.* ::= Tout fichier commençant par un '.'

Exemple de substitution :

echo cat* affichera 'cat*' s'il n'y a aucun fichier commençant par 'cat' dans le répertoire courant. Dans ce cas, il n'y a pas de substitution.

echo /bin/cat* affichera '/bin/cat /bin/catman' car dans ce cas il y a deux fichiers commençant par 'cat' et le SHELL a substitué à l'argument 'cat*' les deux noms trouvés.

cd /bin suivi de 'echo cat*' donnerait le même résultat mais en fin de traitement on reste dans '/bin'.

On peut aussi utiliser des méta-caractères pour la définition d'un path absolu ou partiellement relatif :

echo /*/cat* affichera '/bin/cat /bin/catman /sbin/cat' dans ce cas il y a eu balayage de plusieurs sous-répertoires à partir de '/' et dans ce cas un fichier commençant par 'cat' a été trouvé dans '/sbin' en plus des deux existant dans '/bin'.

Si l'on désire détruire un fichier créé par erreur avec un méta-caractère il faudra s'entourer de précautions car 'rm toto*' détruirait bien le fichier 'toto*' mais aussi tous les fichiers commençant par 'toto'.

Si l'on désire utiliser dans des arguments des caractères spéciaux '*', '?', '[', ']' ou '\' on pourra les masquer avec le caractère '\' devant le caractère spécial désiré :

Exemple :

 ┌────────┐
 │ echo * │     ::= Affiche tous les noms de fichiers contenus dans le
 └────────┘           répertoire courant (sauf ceux qui commencent par un '.').

 ┌─────────┐
 │ echo \* │    ::= Affiche une '*'.
 └─────────┘

 ┌────────────┐
 │ echo toto* │ ::= Affiche 'toto*' s'il n'y a aucun fichier commençant par 'toto' dans le répertoire courant.
 └────────────┘     Affiche tous les noms de fichier du répertoire courant commençant par 'toto' s'il y a au moins un.

 ┌─────────────┐
 │ echo toto\* │ ::= Affichera toujours 'toto*' et sera donc indépendant du contenu du répertoire.
 └─────────────┘       

 ┌──────────────┐
 │ echo 'toto*' │ ::= Affichera toujours 'toto*' et sera donc indépendant du
 │ echo "toto*" │       contenu du répertoire.  (Voir chapitre 'ENCADREMENT DE CHAINES').
 └──────────────┘       

  ┌─────────────────┐
  │ {truc,machin}*  │  désigne tout fichier commençant par 'truc' ou 'machin' voir EXPANSION DES ACCOLADES
  └─────────────────┘  Mais si aucun fichier ne commence par truc, on obtient 'truc*' comme argument 1, et ainsi de suite.

IMPORTANT : Il est important de noter que les commandes n'interprètent pas les méta-caractères mais que le SHELL le fait lors de l'interprétation de la ligne de commande, donc avant l'exécution de celle-ci.

Néanmoins certaines commande comme 'find . -name "fich*" -print' utilisent des méta-caractères dans des arguments de certaines options. Dans ce il est impératif d'encadrer le critère de recherche avec des «"» ou des «'» ou encore de marquer le(s) méta-catactère(s) avec un '\' de façon à éviter l'interprétation par le SHELL de ce ou ces méta-caractères.

  ┌───────────────────────────┐
  │ find . -name fich* -print │  sera interprétée de façon différente selon l'existence ou non de fichiers commençant
  └───────────────────────────┘    par 'fich' dans le répertoire courant.

       ┌───────────────────────────┐
       │ find . -name fich* -print │  S'il n'existe aucun fichier
       └───────────────────────────┘    commençant par 'fich'.

       ┌───────────────────────────┐
       │ find . -name fich1 -print │  S'il n'existe qu'un seul fichier
       └───────────────────────────┘    commençant par 'fich'.

       ┌─────────────────────────────────┐
       │ find . -name fich1 fich2 -print │  S'il existe deux fichiers commençant par 'fich'.
       └─────────────────────────────────┘  Et dans ce cas la commande 'find' est incorrecte, car il y a deux arguments pour une option '-name'.

IMPORTANT : Avant de lancer des commandes comme 'rm' ou 'cp' avec des méta-caractères il est prudent de vérifier le résultat de ces méta-caractères :

      ┌──────────────┐
      │ echo a*[0-9] │  ::=  Affichage des noms de fichiers correspondant
      └──────────────┘       aux méta-caractères spécifiés,
                        ┌────────────┐
        avant de lancer │ rm a*[0-9] │
                        └────────────┘
                                                                 ┌───────────────┐
        ou ne pas oublier de spécifier une demande de validation │ rm -i a*[0-9] │
          fichier par fichier.                                   └───────────────┘




 3.1.1.11 : ENCADREMENT DE CHAINES "...." OU '.....'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Pour résoudre le problème des espaces et ou des caractères spéciaux dans un argument on pourra aussi encadrer un argument avec les caractères :

«'» ou «"» :

   ┌──────────────────┐                  ┌───────┐
   │ echo a   b   c   │     affichera :  │ a b c │
   └──────────────────┘                  └───────┘

   ┌──────────────────┐                  ┌───────────┐
   │ echo "a   b   c" │     affichera :  │ a   b   c │
   └──────────────────┘                  └───────────┘

   ┌──────────────────┐                  ┌───────────┐
   │ echo 'a   b   c' │     affichera :  │ a   b   c │
   └──────────────────┘                  └───────────┘

Et dans les deux cas on pourra utiliser les caractères '*', '?' et '[..]' sans que le SHELL leur substitue des noms de fichiers.

La différence entre «"» et «'» est au niveau de l'interprétation éventuelle des caractères spéciaux '$' '`' et du '\'.

La chaîne contenue entre «'» n'est jamais interprétée par le SHELL.

La chaîne contenue entre «"» est examinée par le SHELL qui remplacera les variables '$nom_var' et les chaînes `cde xxx ...` par leur équivalent. Les caractères '$', '`' et «"» peuvent être marqués par un '\' et seront interprétés comme un seul caractère.

Mais les autres caractères '*', '?', "[...]" ne sont jamais interprétés.

   ┌──────────────┐                     ┌─────────────────────────┐
   │ echo "$PATH" │         affichera : │ /usr/bin:/bin:......... │
   └──────────────┘                     └─────────────────────────┘

   ┌──────────────┐                     ┌───────┐
   │ echo '$PATH' │         affichera : │ $PATH │
   └──────────────┘                     └───────┘

Il est évident que les caractères «"» et «'» deviennent aussi des caractères spéciaux qui de plus ne peuvent être utilisés que par paire Mais l'on pourra utiliser le «"» dans une chaîne encadrée par «"» en le marquant avec un '\'.

              ┌───────────────────┐              ┌───────────┐
    Exemple : │ echo "aaaa\"bbbb" │  affichera : │ aaaa"bbbb │
              └───────────────────┘              └───────────┘

Mais dans le cas d'un encadrement par des «'» il n'y a pas de possibilité d'insérer le caractère «'» dans la chaîne sauf l'introduction de '\047' qui est le code octal du «'», mais ceci uniquement pour les commandes (echo, tr, etc... ) qui interprètent les valeurs octales.

Dans une chaîne encadrée avec des «"» ou des «'» les caractères peuvent être des caractères ASCII composés au clavier ou des valeurs en octal composées sous la forme '\0ooo' (ooo étant la valeur octale désirée) :

            ┌──────────────────┐             ┌───────────────────────────┐
  Exemple : │ echo "Erreur\07" │ affichera : │ Erreur   + la sonnette de │
            └──────────────────┘             │            l'écran .      │
                                             └───────────────────────────┘

On peut, bien sûr, utiliser à la place de certaines valeurs octales les caractères de contrôle "\b", "\n", ... définis dans le chapitre sur le 'backslash', mais rappelons que ceux-ci ne sont pas gérés par le SHELL.

mais par la commande utilisée.

             ┌──────────────────────┐                ┌────────┐
    Exemple :│ echo "ABCDEF\nGHIJK" │ affichera  :   │ ABCDEF │
             └──────────────────────┘                │ GHIJK  │
                                                     └────────┘

A noter que dans une chaîne encadrée par des «"» ou des «'» un seul '\' est à utiliser alors que sans cet encadrement il fallait en utiliser deux (Voir chapitre sur le backslash ).

            ┌────────────┐        ┌────────────┐        ┌────────────┐
            │ echo  \\07 │   ::=  │ echo "\07" │   ::=  │ echo '\07' │
            └────────────┘        └────────────┘        └────────────┘

Mais le SHELL n'est pas en cause puisque les valeurs octales '\0ooo' ou caractères de contrôles (\n,\b,...) ne sont pas gérées par le SHELL mais interprétées par les commandes. Le SHELL envoie '\Oooo', '\n', etc... sans les transformer.

Le tableau suivant résume les possibilités d'interprétation des caractères spéciaux '$','`' et '\' lorsqu'ils sont encadrés par les caractères vus dans ce chapitre ou le chapitre suivant.

             ┌────────────────────────────────────────────┐
             │           M é t a - c a r a c t è r e      │
             ├───┬─────┬─────┬─────┬─────┬─────┬──────────┤
             │   │  '  │  "  │  `  │  \  │  $  │  *,?,[..]│
             ├───┼─────┼─────┼─────┼─────┼─────┼──────────┤
             │ ' │  f  │  n  │  n  │  n  │  n  │  n       │
             ├───┼─────┼─────┼─────┼─────┼─────┼──────────┤
             │ " │  n  │  f  │  y  │  y  │  y  │  n       │
             ├───┼─────┼─────┼─────┼─────┼─────┼──────────┤
             │ ` │  n  │  n  │  f  │  y  │  n  │  n       │
             └───┴─────┴─────┴─────┴─────┴─────┴──────────┘

f ::= Caractère de fin d'encadrement y ::= Le caractère sera interprété à l'intérieur de l'encadrement n ::= Le caractère ne sera pas interprété.

Exemple : echo "$PATH" ::= Affiche le contenu de PATH echo "\$PATH" ::= Affiche les caractères '$PATH' echo '$PATH' ::= Affiche les caractères '$PATH' echo '\$PATH' ::= Affiche les caractères '\$PATH'




 3.1.1.12 : ENCADREMENT DE COMMANDE(S) `cde arg` ou $(cde arg)    Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le caractère '`' (accent grave) permet d'encadrer une commande et de récupérer le résultat de l'affichage de cette commande mais envoyé sous forme d'arguments.

La forme (cde arg) est une variante plus moderne.

Exemple : Mémorisation du répertoire courant dans une variable.

           ┌──────────────┐        ┌───────────────┐
           │ OLDDIR=`pwd` │        │ OLDDIR=$(pwd) │
           │ cd ......    │        │ cd ......     │
           │ .........    │        │ .........     │
           │ .........    │        │ .........     │
           │ cd $OLDDIR   │        │ cd $OLDDIR    │
           └──────────────┘        └───────────────┘

Exemple : Si l'on a un fichier 'toto' contenant des noms de fichiers à examiner.

  ┌────────────────────────────────────┐
  │ echo titi >toto ; echo tutu >>toto │ ::= toto contient 'titi' et 'tutu'
  └────────────────────────────────────┘     sur deux lignes distinctes.

         ┌──────────┐                      ┌──────┐
         │ cat toto │         Affichera :  │ titi │
         └──────────┘                      │ tutu │
                                           └──────┘

         ┌────────────────┐                ┌────────────────────┐
         │ cat `cat toto` │   Affichera :  │ Le contenu de titi │
         └────────────────┘                │ Le contenu de tutu │
                                           └────────────────────┘

         ┌──────────────────┐              ┌──────────────────────────────┐
         │ ls -l `cat toto` │ Affichera :  │ Les caractéristiques de titi │
         └──────────────────┘              │ et de tutu.                  │
                                           └──────────────────────────────┘

Exemple : Si l'on désire mémoriser dans une variable d'environnement le nombre de fichiers contenus dans un répertoire :

                  ┌─────────────────────┐
                  │ nombre=`ls | wc -l` │
                  └─────────────────────┘

Après exécution un 'echo $nombre' permet de vérifier le résultat.

ATTENTION : Ne pas confondre cette commande avec le 'pipe' car dans le cas du 'pipe' des processus sont traités en parallèle avec mise en communication de la sortie standard du premier et l'entrée standard du deuxième.

Dans le cas d'une commande encadrée par des '`' :

- cette commande est d'abord exécutée - l'ensemble encadré est remplacé par l'ensemble des caractères affichés par cette commande et ceux-ci seront donc des arguments de la commande qui précède.

Il est à noter qu'une commande encadrée avec des "`" est exécutée dans un processus fils et que c'est l'affichage exécuté par cette commande qui est substitué à l'encadrement complet.

Si la commande à exécuter possède une redirection de sortie, alors le résultat obtenu est un octet nul.

Il peut y avoir plusieurs commandes dans un seul encadrement de "`" mais dans ce cas les commandes doivent être séparées par des séparateurs de commande. Les affichages résultant de chaque commande seront simplement séparés par le séparateur d'argument.




 3.1.1.13 : '(' et ')' BLOC COMMANDES (cde1 ; .... )   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Les parenthèses '(' et ')' peuvent servir à faire considérer au SHELL l'ensemble des commandes contenues entre ces "()" comme un bloc logique à interpréter par un processus fils.

Chaque commande doit être séparée de la suivante par un séparateur de commandes (';' ou passage à la ligne).

L'intérêt de ce regroupement de commandes est de pouvoir définir une redirection commune, ou un 'pipe' unique ou un lancement en arrière plan unique pour ce bloc.

Exemple :

     ┌────────────────────────────────┐      ┌─────────────────┐
     │ (cat toto ; cat titi ; ) >tutu │  ::= │ cat toto >tutu  │
     └────────────────────────────────┘      │ cat titi >>tutu │
                                             └─────────────────┘
                    ┌───────────────────────────┐
       Par contre : │ cat toto ; cat titi >tutu │
                    └───────────────────────────┘

afficherait le contenu de toto à l'écran et celui de titi dans tutu car dans ce cas la redirection ne s'applique qu'à la dernière commande.

NOTE : Il ne s'agit que d'un exemple simpliste pour illustrer la notion de bloc mais il est évident que dans ce cas on pouvait utiliser : cat toto titi >tutu

    ┌─────────────────────────────┐
    │ (cde1 ; cde2 ; ... ) | .... │   La sortie de chaque commande sera
    └─────────────────────────────┘   envoyée successivement dans le 'pipe'.

    ┌─────────────────────────────┐
    │ (cde1 ; cde2 ; ... ) &      │  Un processus fils sera créé en arrière
    └─────────────────────────────┘  plan pour exécution de la liste de

commandes spécifiées.

EXEMPLE

Cet exemple réalisé sous prompt SHELL montre bien que les commandes entre '()' ont été exécutées dans un processus fils alors que dans le deuxième cas (sans '()') les commandes 'cd' et 'pwd' (commandes internes) ont été exécutées dans le processus courant.

  ┌─────────────────────────────────┐           ┌──────────────┐
  │ $ cd /home/dupond               │  Affiche  │ /home/dupond │
  │ $ pwd ; ( cd /dev ; pwd ) ; pwd │           │ /dev         │
  └─────────────────────────────────┘           │ /home/dupond │
                                                └──────────────┘
  ┌─────────────────────────────┐           ┌──────────────┐
  │ $ cd /home/dupond           │  Affiche  │ /home/dupond │
  │ $ pwd ; cd /dev ; pwd ; pwd │           │ /dev         │
  └─────────────────────────────┘           │ /dev         │
                                            └──────────────┘

Autre exemple avec visualisation du numéro de processus :

Pour réaliser cet exemple nous nous servirons de 'ps -ft nom_terminal' mais, comme 'ps' affiche les processus en cours lors de son exécution il faut ajouter une temporisation 'sleep 1' avant la fermeture des parenthèses pour être sûr que 'ps' ait le temps de voir le processus en cours.

Au moment du 'login' le processus du SHELL courant a comme numéro ('PID=5131'). On pourra suivre les processus fils de celui-ci.

    ┌───────────────────────────────┐
    │ $ ps -ft term/BA451 ; sleep 1 │
    └───────────────────────────────┘

Affiche :

    ┌───────────────────────────────────────────────────────────────────┐
    │    UID   PID  PPID  C    STIME TTY      TIME COMD                 │
    │ dupond  5131   953  0 14:25:15 term/BA451  0:00 -sh               │
    │ dupond  5367  5131  8 14:49:12 term/BA451  0:00 ps -ft term/BA451 │
    └───────────────────────────────────────────────────────────────────┘

La commande 'ps' s'exécute dans un processus fils du SHELL de base ('PID=5131'). (Cas classique et normal).

    ┌───────────────────────────────────┐
    │ $ ( ps -ft term/BA451 ; sleep 1 ) │
    └───────────────────────────────────┘

Affiche :

    ┌───────────────────────────────────────────────────────────────────┐
    │    UID   PID  PPID  C    STIME TTY      TIME COMD                 │
    │ dupond  5131   953  0 14:25:15 term/BA451  0:01 -sh               │
    │ dupond  5372  5131  0 14:52:18 term/BA451  0:00 -sh               │
    │ dupond  5373  5372  8 14:52:18 term/BA451  0:00 ps -ft term/BA451 │
    └───────────────────────────────────────────────────────────────────┘

Un nouveau SHELL ('PID=5372') a été créé pour exécuter les commandes entre "()" et 'ps' a été exécuté dans un processus fils de celui-ci.

CODE DE RETOUR
  ┌─────────────────────────────────────────────────────┐
  │ Le code de retour est celui de la dernière commande │
  └─────────────────────────────────────────────────────┘




 3.1.1.14 : '{' et '}' EXPANSION DES ACCOLADES { arguments }   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

   ┌────────────────────────────────────────────────┐
   │ {1..10}  génère la suite 1 2 3 4 ... 8 9 10    │ 
   │ {a..z}   génère la suite a b c d ...  x y z    │ 
   └────────────────────────────────────────────────┘

Le développement des accolades induit une légère incompatibilité avec les versions traditionnelles de l'interpréteur Bourne sh.

sh n'effectue aucun traitement sur les accolades ouvrantes et fermantes lorsqu'elles apparaissent dans un mot, et les laisse inchangées.

Bash supprime les accolades dans les mots, après développement.

Par exemple, si l'on fournit à sh le mot 'fich{1,2}', il reste inchangé en sortie. Par contre, il est transformé en fich1 fich2 par bash.

Si une compatibilité stricte avec sh est nécessaire, lancez bash avec l'option +B ou désactivez le développement des accolades avec l'option +B de la commande set (voir le paragraphe COMMANDES INTERNES DU SHELL plus bas).

Remarque: Il ne faut pas confondre l'utilisation des accolades pour générer des listes avec l'utilisation des accolades pour lever une ambiguïté sur un nom de variable comme dans "$nom_vara" et "${nom_var}a" ;




 3.1.1.15 : ${...}' REMPLACEMENT PARAMETRES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le caractère « $ » permet d'introduire le remplacement des paramètres, la substitution de commandes, ou l'expansion arithmétique. Le nom du paramètre ou du symbole à développer peut être encadré par des accolades, afin d'éviter que les caractères suivants ne soient considérés comme appartenant au nom de la variable.

Lorsque les accolades sont utilisées, l'accolade finale est le premier caractère « } » non protégé par une barre oblique inverse ni inclus dans une chaîne protégée, ni dans une expresssion arithmétique, une substitution de commande ou un développement de paramètre.

  • ${paramètre} est remplacé par la valeur du paramètre. Les accolades sont nécessaire quand le paramètre est un paramètre positionnel ayant plusieurs chiffres, ou si le paramètre est suivi de caractères n'appartenant pas à son nom.

    Si le premier caractère du paramètre est un point d'exclamation, un niveau d'indirection de variable est introduit. Bash utilise la valeur de la variable formée par le reste du paramètre comme un nom de variable. Cette variable est alors développée et la valeur utilisée pour le reste de la substitution plutôt que la valeur du paramètre lui-même. On appelle ce mécanisme le développement indirect. Les exceptions à celui-ci sont les développements de ${!prefix*} et de ${!nom[@]} décrits plus loin. Le point d'exclamation doit immétiatement suivre l'accolade ouvrante afin d'introduire l'indirection.

    Dans chacun des exemples suivants, le mot est soumis au développement du tilde, au remplacement des paramètres, à la substitution de commandes, et à l'évaluation arithmétique. Bash vérifie si un paramètre existe, et s'il n'est pas nul. L'omission du double point ne fournit qu'un test d'existence.

  • ${paramètre:-mot} Utilisation d'une valeur par défaut. Si le paramètre est inexistant ou nul, on substitue le développement du mot. Sinon, c'est la valeur du paramètre qui est fournie.

  • ${paramètre:=mot} Attribution d'une valeur par défaut. Si le paramètre est inexistant ou nul, le développement du mot lui est affecté. La valeur du paramètre est alors renvoyée. Les paramètres positionnels, et spéciaux ne peuvent pas être affectés de cette façon.

  • ${paramètre:?mot} Affichage d'une erreur si inexistant ou nul. Si le paramètre est inexistant, ou nul, le développement du mot (ou un message approprié si aucun mot n'est fourni) est affiché sur la sortie d'erreur standard, et l'interpréteur se termine, s'il n'est pas interactif. Autrement, la valeur du paramètre est utilisée.

  • ${paramètre:+mot} Utilisation d'une valeur différente. Si le paramètre est nul, ou inexistant, rien n'est substitué. Sinon le développement du mot est renvoyé.

  • ${paramètre:début}
  • ${paramètre:début:longueur} :: substr(chaine,offset,longueur) Extraction de sous-chaîne Se développe pour fournir la sous-chaîne de la longueur indiquée (en caractères) commençant au début.D offset. Si la longueur est omise, fournit la sous-chaîne commençant au caractère de début et s'étendant jusqu'à la fin du paramètre. La longueur et le début sont des expressions arithmétiques (voir ÉVALUATION ARITHMÉTIQUE plus bas). La longueur doit être positive ou nulle. Si le début est négatif, sa valeur est considérée à partir de la fin du contenu du paramètre. Si le paramètre est @, le résultat correspond aux longueur paramètres positionnels commençant au début. Si le paramètre est un nom de tableau indexé par @ ou *, le résultat est les longueur membres du tableau commençant à ${paramètre[début]}. Une valeur négative de début est prise relativement à la valeur maximum de l'index du tableau considéré, augmentée de un. Notez qu'une valeur négative de début doit être séparée du deux-points par au moins une espace pour éviter toute confusion avec le dévéloppement de « :- ». L'indexation des sous-chaînes débute à zéro, sauf pour les paramètres positionnels qui débute en 1.

  • ${#paramètre}
  • ${!paramètre@} Se développe en les noms des variables dont les noms commencent par paramètre, séparés par le premier caractère de la variable spéciale IFS
  • ${!nom[@]}
  • ${!nom[*]} Si nom est une variable de type tableau, elle se développe en la liste des indices (clés) du tableau affecté à nom.

    Si nom n'est pas un tableau, se développe en 0 si existe et en rien autrement.

    Si @ est utilisé et que le développement apparaît entre guillemets, chaque clé se développe en un mot séparé.

    Est remplacé par la longueur, en caractères, de la valeur du paramètre.

    Si le paramètre est * ou @, la valeur est le nombre de paramètres positionnels.

    Si le paramètre est un nom de tableau indexé par * ou @, la valeur est le nombre d'éléments dans le tableau.

  • ${paramètre#mot}
  • ${paramètre##mot} Le mot est développé pour fournir un motif, comme dans l'expansion des noms de fichiers. Si le motif correspond au début de la valeur du paramètre, alors le développement prend la valeur du paramètre après suppression du plus petit motif commun (cas « # »), ou du plus long motif (cas « ## »). Si le paramètre est @ ou *, l'opération de suppression de motif est appliquée à chaque paramètre positionnel successivement, et le développement donne la liste finale. Si le paramètre est une variable tableau indexée par @ ou *, l'opération de suppression de motif est appliquée à chaque membre du tableau successivement, et le développement donne la liste finale.

  • ${paramètre%mot}
  • ${paramètre%%mot} est développé pour fournir un motif, comme dans l'expansion des noms de fichiers. Si le motif correspond à une portion finale de la valeur du paramètre, alors le développement prend la valeur du paramètre après suppression du plus petit motif commun (cas « % »), ou du plus long motif (cas « %% »). Si le paramètre est @ ou *, l'opération de suppression de motif est appliquée à chaque paramètre positionnel successivement, et le développement donne la liste finale. Si le paramètre est une variable tableau indexée par @ ou *, l'opération de suppression de motif est appliquée à chaque membre du tableau successivement, et le développement donne la liste finale.

  • ${paramètre/motif/chaîne} Le motif est développé comme dans le traitement des noms de fichiers.

    Le paramètre est développé et la plus longue portion correspondant au motif est remplacée par la chaîneg. Si le motif commence par /, toutes les correspondances de motif sont remplacés par chaîne. Normalement, seule la première correspondance est remplacée. Si le motif commence par #, il doit correspondre au début de la valeur développée du paramètre. Si le motif commence par %, il doit correspondre à la fin du développement du paramètre. Si la chaîne est nulle, les portions correspondant au motif sont supprimées et le / après le motif peut être omis.

    Si le paramètre est @ ou *, l'opération de substitution est appliquée à chacun des paramètres positionnels successivement, et le résultat est la liste finale. Si le paramètre est une variable tableau indexée par @ ou *, l'opération de substitution s'applique à chaque membre du tableau successivement, et le résultat est la liste finale.






  •  3.1.1.16 : nom_fonction () { cde1 ; ....; } FONCTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Une fonction SHELL se définit avec un nom qui suivra la règle des noms de variables d'environnement. Et une fois définie, elle apparaît dans l'affichage de l'environnement (voir 'set') comme mélangée aux variables d'environnement. En conséquence un nom de fonction devra toujours être distinct des noms de variables. De même les noms de variables devront être distincts des noms de fonctions car si quelqu'un utilise le nom d'une fonction comme nom de variable, lors d'une affectation de contenu, la fonction disparaît au profit du contenu de ce qui sera considéré comme une variable et non plus une fonction ou inversement.

                    ┌─────────────────┐    ┌─────────────────────────────────┐
      fonction  ::= │ nom_fonction(){ │ ou │ nom_fonction () { liste_cde ; } │
                    │   instruct_1    │    └─────────────────────────────────┘
                    │   instruct_2    │
                    │   .........     │
                    │ }               │
                    └─────────────────┘
    

    A noter : Un espace obligatoire entre le '{' et la première commande et le ';' obligatoire si la fonction est définie sur une seule ligne.

     ┌──────────────────────┐
     │ l () { ls -la $* ; } │ ::=  Définition d'une fonction 'l' qui à chaque
     └──────────────────────┘      appel fera en fait un 'ls -la' suivi des
    

    arguments d'appel de 'l'.

    Une fois définie, la fonction 'l' peut être affichée avec la commande 'set' et elle apparaîtra sous la forme :

                            ┌────────────┐
                            │  l () {    │
                            │  ls -la $* │
                            │  }         │
                            └────────────┘
    

    dans la liste des variables et des fonctions d'environnement.

    De plus la commande 'type l' affiche que 'l' est une fonction et affiche aussi la définition de la fonction.

    La commande 'return' permet de gérer la sortie d'une fonction avec la spécification éventuelle d'un code retour.

                                      ┌────────────┐
          Sortie d'une fonction  ::=  │ return [n] │
                                      └────────────┘
    

    ATTENTION : Une fonction ne peut pas être exportée d'un SHELL vers un processus fils.

    Mais l'utilisation principale des fonctions est dans l'écriture de scripts SHELL (Voir CHAPITRE PROGRAMMATION FONCTIONS SHELL).




     3.1.2 : ETAPES EXECUTION COMMANDE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre décrit comment le SHELL interprète une ligne de commandes.

    Pour bien comprendre ce que fait le SHELL lors du traitement d'une ligne de commandes, il est important de connaître tous les mécanismes utilisés par ce SHELL. Ce détail n'est pas nécessaire pour le lancement de commandes simples mais il est très utile dès que l'on voudra réaliser des appels complexes de commandes.

    En fait comme vu dans le chapitre 'SHELL langage de programmation', le SHELL interprète de la même façon des commandes composées de façon interactive au clavier ou des commandes stockées dans un fichier appelé 'script SHELL'

    Une ligne de commandes est constituée d'une seule commande ou d'une suite de commandes séparées par des séparateurs de commandes.

    Dans une ligne saisie au clavier le séparateur est un ';', alors que dans un script, il peut aussi s'agit d'un caractère de retour à la ligne.

    Le SHELL interprète les commandes dans l'ordre de saisie et les exécute.

    Une commande doit être constituée d'un premier mot qui devra être soit une commande (interne ou externe) soit une instruction.

    Les étapes suivies par le SHELL sont importantes à connaître pour être sûr que celui-ci exécutera bien ce que vous demandez.

    1 ::= Le SHELL lit la ligne de commande, cherche le premier caractère de séparation de commandes (non marqué par un '\') et examine les '\' et les caractères d'encadrement de chaînes (",' ou `).

    2 ::= Il examine les redirections et les assignations de variables.

    (<,>,.... et =) >toto , <titi , total=......

    3 ::= Il éclate la ligne de commande en arguments séparés et recherche les couples de mots-clés formant un bloc logique ou les couples de parenthèses '(....) ou { .... } '.

    Les séparateurs d'arguments sont les espaces et les tabulations.

    La variable 'IFS' n'intervient pas à ce niveau mais sera utilisée dans l'étape 8.

    Il y a aussi dans cette étape la recherche en premier argument d'un des mots-clés ou caractères suivants :

    'if', 'elif', 'case', 'for', 'while', 'until', '{' ou '('.

    Si un de ces mots-clés ou caractères est trouvé, alors il y a répétition des étapes 1 et 3 sur la même ligne ou les lignes suivantes jusqu'à trouver le mot-clé ou le caractère de fin correspondant : 'fi', 'esac', 'done', '}' ou ')'.

    En cas d'erreur de syntaxe, il y aura un message d'erreur et abandon de la ligne de commandes.

    4 ::= Il substitue les noms de variables par leurs contenus

    $0 $1 .... $* $@ $# $? $! $$ $- $nom_variable ${...} Tout nom de variable non référencé est remplacé par un octet nul.

    5 ::= Il exécute les commandes entre "`" et y substitue le résultat de l'affichage de leurs exécutions.

    Si une commande est redirigée dans un fichier, alors le résultat de l'encadrement de cette commande par des "`" est un octet nul.

    Il peut y avoir plusieurs commandes entre une seule paire de "`", mais dans ce cas elles doivent être séparées par des séparateurs de commande.

    6 ::= Il re-dirige les entrées/sorties standard vers le ou les fichiers spécifiés.

    Exécution des redirections détectées lors de l'étape 2.

    7 ::= Il exécute l'assignation des variables Si la ligne de commande ne contient qu'une ou plusieurs instructions d'assignation mais pas d'autre commande, alors les variables sont initialisées avec les valeurs indiquées pour l'environnement courant, et les étapes suivantes sont ignorées.

    Si le SHELL a été appelé avec l'option '-a, alors les variables sont automatiquement exportées. Dans le cas contraire, il reste à les exporter avec une instruction 'export'.

    Si la ligne de commande contient une ou plusieurs assignations et une autre commande, alors la variable ou les variables ainsi assignées feront partie de l'environnement de cette commande mais pas de l'environnement courant si cette commande doit s'exécuter dans un processus fils (commande externe).

    Si le SHELL a été appelé avec l'option '-k', alors les assignations peuvent se trouver derrière la commande à exécuter et l'étape 7 recherche toutes les assignations figurant devant ou derrière la commande pour les effectuer avant de passer aux étapes suivantes.

    8 ::= Il recommence l'éclatement de la ligne ainsi obtenue en arguments séparés (en fonction de la variable 'IFS').

    Par défaut les séparateurs d'arguments pour cette étape sont les espaces, les tabulations et les passages à la ligne, mais les passages à la ligne ne sont plus interprétés comme des séparateurs dans cette étape.

    Si 'IFS' est initialisé à un ou plusieurs caractères, alors chaque caractère contenu dans 'IFS' est remplacé par un espace.

    Cette étape est complémentaire de l'étape 3 mais entre temps il y a eu :

    Remplacement des variables par leurs valeurs.

    Exécution des commandes entre "`" et substitution par leurs affichages.

    Les couples, de mots-clés 'if ... fi' 'case ... esac' ou de parenthèses, ont été recherchés et traités.

    Les redirections ont été traitées.

    9 ::= Il exécute les substitutions des méta-caractères de génération de noms de fichiers (*, ? [...], et [!...]).

    Si une chaîne contenant un ou plusieurs méta-caractères correspond à plusieurs noms de fichiers, ceux-ci sont fournis en ordre alphabétique croissant.

    Si l'option '-f' du SHELL est positionnée cette étape est ignorée et il n'y a pas de substitution des méta-caractères.

    Si l'option '-n' du SHELL est positionnée alors le traitement s'arrête à cette étape car on n'exécute pas réellement les commandes.

    10 ::= Il exécute la ligne de commande.

    Cette exécution sera différente selon le type exact de la commande à traiter :

    Commande interne du SHELL : Exécution dans l'environnement courant.

    Fonction du SHELL : Exécution de la fonction dans l'environnement courant.

    Autres commandes : Préparation d'un processus fils (avec 'fork ()') ce processus héritera de l'environnement courant mais seulement des variables exportées.

    Ce nouveau SHELL examinera le nom de la commande :

    Nom de commande contenant un '/' : La commande est passée à 'exec ()' sans passer par le contenu de $PATH :

    Si l'option '-r' du SHELL est positionnée une telle commande est rejetée. (SHELL restreint) Nom de commande ne contenant pas de '/' : Le SHELL cherche le nom dans la table 'hash' courante (Voir 'hash').

    Si ce nom est contenu dans la table 'hash', alors on passe la commande à 'exec ()' sous la forme d'un path mais sans passer par le contenu de $PATH.

    Si ce nom n'est pas contenu dans la table 'hash', alors il y a formation d'un path absolu avec le premier répertoire contenu dans $PATH et passage de ce path absolu à 'exec ()'.

    Si 'exec ()' ne peut pas l'exécuter (inexistante ou droits insuffisants, etc...), il y aura retour à ce stade pour la suite du contenu de $PATH.

    La commande 'exec ()' charge la commande en mémoire pour exécution :

    Si la commande est chargeable en mémoire, elle commencera son exécution dès la fin de ce chargement.

    Pour les commandes lancées en arrière plan, il y a retour au 'prompt'.

    Pour les autres commandes le SHELL attendra la fin d'exécution pour afficher le 'prompt'.

    Les commandes lancées avec un nom sans préfixe (voir 'basename') mettent à jour la table 'hash'. La commande 'hash' sans argument permet de visualiser cette table (Voir 'hash')

    Si la commande n'est pas exécutable, il y a affichage d'un message d'erreur :

    Si le nom de commande était spécifié avec un path, ou si cette commande était dans la table 'hash', et que la commande est inaccessible, alors il y a affichage du message :

    'nom_commande : not found'

    Si un nom de commande spécifié sans path n'était pas dans 'hash' il y a eu préparation d'un path absolu à partir du premier répertoire contenu dans $PATH. Si cette commande n'est pas accessible dans le premier répertoire, alors il y aura exploitation des autres répertoires contenus dans $PATH jusqu'à trouver la commande. Si la commande n'est pas trouvée il y a affichage du message :

                     ┌──────────────────────────┐
                     │ nom_commande : not found │
                     └──────────────────────────┘
    

    Si la commande existe mais n'a pas de droits d'exécution pour l'utilisateur, alors pour les commandes ayant été traitées avec $PATH, il y aura retour pour chercher dans le répertoire suivant.

    Pour les autres commandes on aura le message :

                     ┌──────────────────────────────────┐
                     │ nom_commande : permission denied │
                     └──────────────────────────────────┘
    

    Si un fichier n'est pas en code exécutable (compilé 'a.out') tout en ayant des droits d'exécution, alors il est considéré comme un script SHELL.

    Le SHELL lit le contenu du fichier comme s'il s'agissait d'un script. Ceci aboutit souvent, si le fichier ne contient pas réellement des commandes SHELL, à des erreurs de syntaxe détectées par le SHELL si un fichier est déclaré exécutable par ses droits mais que son contenu n'est pas en langage machine ou n'est pas un script SHELL.

                    ┌────────────────────────────────────────────────────────┐
                    │ nom_commande : syntax error at line 1 : '(' unexpected │
                    └────────────────────────────────────────────────────────┘
    




     3.1.3 : NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre a pour objet de détailler la norme de présentation des options et des arguments dans un appel de commande.

    Une commande peut être appelée avec des options et ou des arguments.

        ┌─────────────────────────────────────────────────┐
        │ nom_cde [ -options ... ] [ -- ] [ arg_cde ... ] │
        └─────────────────────────────────────────────────┘
    

    Les caractères "[]" encadrent ce qui n'est pas obligatoire, certaines commandes peuvent être exécutées sans option ni argument. Ce qui fait que tous les éléments d'appel d'une commande sont dans cet exemple tous encadrés par des "[]".

    Les caractères '...' indiquent que l'on peut répéter plusieurs fois le même genre d'élément.

     ┌───────┐
     │nom_cde│  ::=  Nom d'une commande exécutable :
     └───────┘       Commande interne du SHELL
    

    Fonction utilisateur Commande externe (programme exécutable ou script SHELL)
     ┌────────┐      ┌───────────────────────────────┐
     │-options│ ::=  │ -liste_car_opt ...            │
     └────────┘      │ -liste_car_optarg arg_opt ... │
                     └───────────────────────────────┘
    

    Il existe deux types d'options :

    - Les options simples qui peuvent être exprimées isolément ou regroupées.

    - Les options qui attendent un argument d'option (comme un nom de fichier lié à cette option) et dans ce cas on doit spécifier, le caractère d'option, et l'argument d'option, séparés par au moins un espace. Ce type d'option peut être précédé d'autres caractères d'options simples mais ne peut pas être suivi par d'autres caractères même d'options simples, puisque l'on doit spécifier l'argument d'option juste derrière.

             ┌────────────────┐
             │ -liste_car_opt │     ::= Chaîne de caractères commençant de
             └────────────────┘           façon normalisée par un '-' et
    

    contenant un ou plusieurs caractères représentant la ou les options désirées.

    Exemple d'équivalences :

           ┌───────────────────┐     ┌─────────────┐     ┌───────────────┐
           │nom_cde -a -b -c -d│ ::= │nom_cde -abcd│ ::= │nom_cde -a -bcd│
           └───────────────────┘     └─────────────┘     └───────────────┘
    

             ┌──────────────────────────┐
             │ -liste_car_optarg argopt │ ::= Comme précédemment mais le dernier
             └──────────────────────────┘ caractère d'option spécifié correspond
    

    à une option qui attend un argument lié à cette option.

    Exemples d'option '-o' attendant un nom de fichier :

               ┌──────────────────┐     ┌────────────────┐
               │nom_cde -a -o toto│ ::= │nom_cde -ao toto│
               └──────────────────┘     └────────────────┘
    

    L'option '-a' est une option simple, tandis que l'option '-o' attend un argument d'option.

    ATTENTION : Les deux syntaxes suivantes sont peut-être tolérées par certaines commandes mais ne correspondent pas à la normalisation standard.

               ┌─────────────────┐    ┌───────────────┐
               │nom_cde -a -ototo│ ou │nom_cde -aototo│ devraient être évitées.
               └─────────────────┘    └───────────────┘
    

       ┌───────────────┐
       │ nom_cde -o -a │  ::= Dans ce cas '-a' est considéré comme l'argument
       └───────────────┘        de l'option '-o' et non pas comme une option.
    

     ┌───────┐
     │arg_cde│  ::=  Chaîne de caractères ne commençant normalement pas par un
     └───────┘       '-'. Il s'agit souvent dans l'appel d'une commande des
    

    noms de fichiers à traiter.

    Exception à la règle du '-' : le caractère '-' seul, sans autre caractère, spécifie de façon normalisée le fichier d'entrée standard.

    REGLES STANDARD DE SYNTAXE

    1 ::= La longueur d'un nom de commande doit être comprise entre 2 et 9 caractères.

    2 ::= Un nom de commande ne doit comporter que des lettres minuscules ou des chiffres.

    3 ::= Chaque option doit être spécifiée au moyen d'un seul caractère appelé caractère d'option.

    4 ::= Chaque option (ou série d'options voir règle 5) doit être précédée par un caractère '-'.

    5 ::= On peut regrouper entre elles des options simples en une seule série d'option.

    6 ::= Pour une option attendant un argument d'option on doit spécifier cette option suivie d'une espace et de l'argument désiré.

    7 ::= Si l'on spécifie une option attendant un argument l'argument de cette option est obligatoire (n'est pas optionnel) C'est l'ensemble "Option+Argument_d'option" qui est optionnel.

    8 ::= Si une option attend plusieurs arguments, alors ces arguments doivent être spécifiés comme une seule chaîne de caractères, soit séparés par des ',' mais sans aucun espace, soit encadrés par des «"» ou des «'» et dans ce dernier cas on pourra spécifier des espaces dans l'encadrement.

                     ┌─────────────┐       ┌───────────────┐
                     │ -o xxx,z,yy │  ::=  │ -o "xxx z yy" │
                     └─────────────┘       └───────────────┘
    

    9 ::= Toutes les options (et éventuellement les arguments des options attendant un argument) doivent être spécifiées avant les arguments de la commande.

    10 ::= La chaîne '--' peut être utilisée comme séparateur logique entre 'options' et 'arguments de commandes'. Mais ceci ne doit pas être obligatoire.

                      ┌─────────────────┐
                      │ cde -b -c -- -a │ Permet donc de faire considérer le
                      └─────────────────┘ dernier '-a' comme un argument de
    

    la commande et non pas de la spécification de l'option '-a'.

    11 ::= Le déroulement d'une commande doit être indépendant de l'ordre de saisie des options.

                   ┌──────────┐     ┌──────┐     ┌────────┐
                   │ -a -b -c │ ::= │ -abc │ ::= │ -c -ab │ etc....
                   └──────────┘     └──────┘     └────────┘
    

    12 ::= L'ordre de spécification des arguments peut par contre avoir une influence sur le déroulement de la commande.

                   ┌─────────────┐
                   │ cp sce dest │   arg1=Fic.source  arg2=Fic.destination
                   └─────────────┘
    

    13 ::= Un seul '-' précédé et suivi d'au moins un espace ne peut être utilisé que pour spécifier le fichier d'entrée standard.

    La commande interne 'getopts' qui aide les programmeurs à analyser les options respecte les règles de 3 à 10. (Voir 'getopts').

    ATTENTION : Ces normes doivent être appliquées en principe par toutes les commandes, mais un petit nombre des commandes standard ne les appliquent par intégralement.

    NOTES Un autre standard d'écriture de commande fait qu'en cas d'erreur de syntaxe sur l'appel (options incorrectes, incompatibles, etc...) la commande doit afficher une clause 'usage' définissant la syntaxe d'appel de la commande :

            ┌────────────────────────────────────────────────────────┐
            │ Usage: nom_cde [ -a | -b ] [ -o fic_dest ] fic_sce ... │
            └────────────────────────────────────────────────────────┘
    

    Si une commande respecte ce standard l'appel 'nom_cde -\?' doit afficher cette clause usage et permettre un rappel rapide de la syntaxe de la commande (avec éventuellement un message d'erreur dû à l'utilisation d'une option '?' non définie pour la commande).

                                    ┌───────────────────────────────────┐
                                    │ cp: ERROR: Illegal option -- ?    │
            ┌────────┐              │ cp: Insufficient arguments (0)    │
            │ cp -\? │   Affiche    │ Usage: cp [-i] [-p] f1 f2         │
            └────────┘              │        cp [-i] [-p] f1 ... fn d1  │
                                    │        cp [-i] [-p] [-r] d1 d2    │
                                    └───────────────────────────────────┘
    

    D'autres commandes utilisent '-help' pour afficher la liste des options, mais il ne s'agit pas d'un standard.




     3.2 : VARIABLES D'ENVIRONNEMENT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le SHELL ne connaît que des variables simples et des tableaux de variables à une dimension.

    Par défaut une variable sera de type alphanumérique, mais l'instruction declare permetta de déclarer explicitement des types de variables (Mais nous sommes loin d'un langage très typé comme le 'C').

    On pourra aussi déclarer des attributs comme 'readonly' avec declare.

    Le nom d'une variable commence obligatoirement par une lettre suivie éventuellement de lettres, chiffres ou le caractère '_'.

    Par convention les variables d'environnement nécessaires à un logiciel seront en MAJUSCULES alors que celles utilisées de façon temporaire seront en minuscules de façon à ne pas détruire des variables nécessaires à d'autres commandes.

    L'utilisation d'une variable non initialisée ne provoque pas d'erreur (sauf option '-u' du SHELL ou de 'set') le contenu est alors considéré comme une chaîne vide (absence de caractère).

    On peut visualiser facilement les variables d'environnement standard avec 'env' et l'ensemble de l'environnement avec 'set'.

            ┌─────┐         ┌─────┐
            │ env │         │ set │
            └─────┘         └─────┘
    

    On peut initialiser une variable avec la commande 'env nom=valeur' (Voir le chapitre 'env') mais on peut aussi utiliser sous SHELL une commande d'affectation 'nom=valeur' (Voir chapitre suivant)

    Si l'on désire supprimer une variable d'environnement on peut utiliser la commande 'unset' :

            ┌──────────────────────┐
            │ unset <nom_variable> │
            └──────────────────────┘
    

    On invoque le contenu d'une variable en utilisant le caractère '$' devant le nom de la variable. Dans certains cas afin de lever des ambiguïtés de syntaxe on encadrera le nom de la variable par des "{}" juste derrière le '$'.

                     ┌───────┐      ┌─────────┐
        Exemple :    │ $VAR1 │ ::=  │ ${VAR1} │
                     └───────┘      └─────────┘
      ┌────────────────────────────────────────────────────────────────────────┐
      │ echo $TERM     affiche xterm                                           │
      │ echo A$TERM    affiche Axterm                                          │
      │ echo $TERMB    affiche une chaîne vide s'il n'y a pas de variable TERMB│
      │ echo ${TERM}B  affiche xtermB                                          │
      └────────────────────────────────────────────────────────────────────────┘
    

    Note : les caractères {} servent aussi à l'initialisation conditionnelle d'un nom de variable ou à la substitution conditionnelle d'un nom de variable et d'un contenu (Voir chapitre AFFECTATION CONDITIONNELLE ou SUBSTITUTION CONDITIONNELLE).




     3.2.1 : AFFECTATION DE VARIABLES D'ENVIRONNEMENT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    On initialise ou modifie le contenu d'une variable en utilisant l'instruction "=" entre le nom de la variable et le contenu désiré.

    ATTENTION : Le caractère '=' devra être placé immédiatement après le nom de la variable afin de lever l'ambiguïté avec l'appel d'une commande qui aurait le même nom que la variable et comme argument le caractère '='.

    Même remarque pour le contenu désiré qui doit suivre immédiatement le caractère '='.

                            ┌────────────┐               ┌──────────────┐
                  Exemple : │ nom=DUPOND │   et non pas  │ nom = DUPOND │
                            └────────────┘               └──────────────┘
    

    On appelle cette instruction une 'affectation'.

        ┌─────────────────────────────────────────────────────┐
        │  nom_var1=valeur1 [ nom_var2=valeur2 .... ]         │ Affectation
        │  nom_var1=valeur1 [ nom_var2=valeur2 .... ] nom_cde │ Aff. + exéc.cde
        └─────────────────────────────────────────────────────┘
    

    Le format 1 correspond à des affectations de variables dans l'environnement courant.

    Le format 2 correspond à des affectations de variables et au lancement d'une commande. Il est à noter que les variables sont affectées dans l'environnement où s'exécutera la commande. Si la commande est une commande externe, alors c'est le processus fils qui contient les affectations de variables et l'environnement courant n'est pas modifié.

    (Voir le chapitre EXECUTION COMMANDE )

    Si le contenu désiré comporte des espaces ou des caractères spéciaux interprétés par le SHELL il faudra encadrer la valeur désirée par des «'» ou des «"» selon le type d'interprétation désiré (Voir le chapitre "CARACTERES SPECIAUX DU SHELL").

                      ┌────────────────────────────────────────────────────────┐
         Exemple :    │ VAR1=abcdef              # Initialisation d'une chaîne │
                      │ VAR1="Nom fichier"       # Initialisation avec espace  │
                      │ VAR1=""                  # Initialisation à vide       │
                      └────────────────────────────────────────────────────────┘
    

    ATTENTION : L'affectation d'une variable avec un contenu ne suffit pas à faire en sorte que ce contenu soit accessible aux processus fils de celui où a lieu la définition.

    Si nécessaire faire une 'exportation' avec la commande 'export'.

    ATTENTION : La fonction d'affectation '=' ne teste pas si la variable était déjà définie et avec ou sans contenu.

    (Voir le chapitre AFFECTATION CONDITIONNELLE ou le chapitre PROTECTION DE MODIFICATION DE VARIABLE)

    ATTENTION : Les fonctions pré-définies dans des fichiers comme 'etc/profile' ou définies manuellement dans son propre environnement du genre 'p() {pwd}' font partie de l'environnement et on ne doit pas utiliser de nom de fonction comme nom de variable d'environnement sous peine de détruire la définition de la fonction. Et inversement.

    ATTENTION : L'affectation d'une variable avec des valeurs octales "=\\0ooo" ou de caractères de contrôle "=\n" stocke dans la variable la chaîne spécifiée sans interprétation.

    'ESC=\\033' stockera '\033' et non pas le caractère octal '33'.

    Si l'on désire obtenir le code 'ESC' dans une variable 'ESC' il faudra utiliser la commande 'echo' :

                            ┌───────────────────┐
                            │ ESC=`echo "\033"` │
                            └───────────────────┘
    




     3.2.1.1 : PROTECTION DE MODIFICATION DE VARIABLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La commande 'readonly' permet de :

       ┌───────────────────────┐
       │ readonly nom_variable │  ::=   Protéger la variable spécifiée contre
       └───────────────────────┘        une modification.
    

       ┌──────────┐
       │ readonly │               ::=   Sans argument spécifié la commande 'readonly'
       └──────────┘                       affiche la liste des variables protégées.
    

    ATTENTION : La commande 'readonly' n'exporte pas la variable et si l'on fait un 'export' de cette variable la protection de modification ne suit pas.




     3.2.2 : AFFECTATION DE VARIABLES+EXECUTION COMMANDE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Si, dans une même commande, on trouve une ou plusieurs affectations de variables et une commande, alors le SHELL considérera que si la commande doit être exécutée dans un processus fils, les affectations doivent se faire pour ce processus et non pas dans le processus courant.

    C'est le cas pour les commandes externes ou les scripts SHELL. (Pour plus de détails voir le chapitre 'ETAPES EXECUTION COMMANDE').

    C'est un moyen simple de lancer une commande avec un environnement désiré sans être obligé de modifier l'environnement courant et d'exporter les variables nécessaires.

    Exemple :

    Si l'on désire exécuter un script SHELL ou une commande externe avec la variable 'toto' affectée avec une valeur sans pour autant l'affecter dans l'environnement courant on peut utiliser :

          ┌───────────────────────────┐
          │ toto="coucou" nom_script  │
          │ toto="coucou" nom_cde_ext │
          └───────────────────────────┘
    

    Dans ce cas le script s'exécute dans un processus fils dans lequel la variable 'toto' a été affectée avec la valeur spécifiée, mais cette affectation n'a eu lieu que dans le processus fils.

    Avec l'option '-k' du SHELL (voir 'set'), il est possible de spécifier la ou les affectations de variables derrière le nom de la commande.

          ┌───────────────────────────┐
          │ nom_script toto="coucou"  │
          │ nom_cde_ext toto="coucou" │
          └───────────────────────────┘
    

    ATTENTION : La substitution des noms de variable par leur contenu est exécutée par le SHELL avant l'exécution de la commande.

    En conséquence si l'on désire charger un contenu dans une variable et que l'on utilise cette variable dans les arguments de la commande, alors c'est le contenu de l'environnement courant qui est substitué et non pas le contenu spécifié. Celui-ci ne sera valable que dans le processus fils.

    (Voir détail dans le chapitre 'ETAPES EXECUTION COMMANDE').

          ┌───────────────────────────┐
          │ repert=/u0/tmp ls $repert │
          └───────────────────────────┘
    

    n'a pas vraiment de sens puisque c'est le contenu actuel qui sera substitué. La commande 'ls' travaille avec les arguments spécifiés (donc, dans ce cas, substitués) et non pas le contenu des variables utilisées.

    ATTENTION : Cette possibilité n'est valable que pour des commandes externes ou des scripts SHELL. En effet si la commande spécifiée est une commande interne du SHELL, celle -ci ne s'exécute pas dans un processus fils et le chargement de la ou des variables spécifiées se fait dans l'environnement courant.

            ┌──────────────────────┐
            │ toto="coucou" cd ../ │ 'cd' est une commande interne et donc
            └──────────────────────┘ le chargement de la variable se fait
    

    dans l'environnement courant.




     3.2.3 : AFFECTATION CONDITIONNELLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le fait d'utiliser une variable d'environnement non définie ou vide n'entraîne pas d'erreur pour le SHELL mais la substitution se fait avec une chaîne vide.

    L'affectation conditionnelle permet d'affecter une variable :

                                                ┌───────────────┐
         Si elle n'est pas définie          ::= │ ${nom=valeur} │
                                                └───────────────┘
    

                                                ┌────────────────┐
         Si elle n'est pas définie ou nulle ::= │ ${nom:=valeur} │
                                                └────────────────┘
      ┌───────────────┐
      │ ${nom=valeur} │  ::=  Si la variable 'nom' n'est pas définie alors
      └───────────────┘         il y a affectation de la variable avec la
    

    valeur et substitution de la chaîne ${....} par cette valeur (comme si on avait simplement $nom).

                 ┌──────────────────────────────────────┐
       Exemple : │ unset nombre                         │
                 │ echo ${nombre=123}    Affichera 123  │
                 │ echo $nombre          Affichera 123  │
                 │ echo ${nombre=124}    Affichera 123  │
                 │ echo $nombre          Affichera 123  │
                 └──────────────────────────────────────┘
    

    La deuxième tentative d'affectation conditionnelle n'a pas modifié le contenu puisqu'il y en avait déjà un.

      ┌────────────────┐
      │ ${nom:=valeur} │ ::=  Si la variable 'nom' n'est pas définie ou
      └────────────────┘        si son contenu est nul, alors il y a affectation
    

    de la variable avec la valeur et substitution de la chaîne ${....} par cette valeur (comme si on avait simplement $nom).




     3.2.4 : SUBSTITUTION CONDITIONNELLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La substitution conditionnelle ressemble à l'affectation conditionnelle mais il n'y a que substitution, et non pas affectation ou modification de la variable.

      ┌───────────────┐
      │ ${nom-valeur} │  ::=  Si la variable 'nom' n'est pas définie alors
      └───────────────┘         il y a substitution de la chaîne ${....}
    

    par cette valeur (comme si $nom contenait cette valeur) mais la variable reste non définie.

      ┌────────────────┐
      │ ${nom:-valeur} │ ::=  Si la variable 'nom' n'est pas définie ou si son
      └────────────────┘        contenu est nul, alors il y a substitution
    

    de la chaîne ${....} par cette valeur (comme si $nom contenait cette valeur). Mais il n'y a pas de définition ou d'affectation de la variable.

                 ┌─────────────────────────────────────────────────┐
       Exemple : │ unset nombre                                    │
                 │ echo ${nombre-123}    Affichera 123             │
                 │ echo $nombre          Affichera une chaîne vide │
                 │ echo ${nombre-124}    Affichera 124             │
                 │ echo $nombre          Affichera une chaîne vide │
                 └─────────────────────────────────────────────────┘
    

    Les substitutions conditionnelles affichent bien le résultat désiré mais la variable reste non définie.

    Exemple d'utilisation :

     ┌───────────────┐
     │ ${rep:-`pwd`} │ ::=  Donnera le contenu de '$rep' si $rep est défini
     └───────────────┘        et dans le cas contraire il y aura substitution
    

    par le résultat de la commande 'pwd' (répertoire courant)




     3.2.5 : VARIABLES DE TYPE TABLEAU 'tableau[indice]'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le SHELL gère des tableaux de variable à une dimension.

    Les indices d'un tableau commencent à partir de 0.

     nom_tableau[indice]=valeur    ::= Assignation d'une valeur à un indice de tableau 
     truc[0]=abcde                 ::= Aprés exécution, la variable truc sera considérée comme un tableau et l'indice 0
                                        de ce tableau contiendra 'abcde'
     truc[1]=fghi                  ::= Aprés exécution, le tableau est agrandi et l'indice 1 de ce tableau contiendra 'fghi'
     truc[]=jklmno                 ::= Aprés exécution, le tableau est agrandi et l'indice 2 de ce tableau contiendra 'jklmno'
     truc[5]=xyz                   ::= Aprés exécution, le tableau est agrandi et l'indice 5 de ce tableau contiendra 'xyz'
     echo ${truc[0]}               ::= Affiche abcde
     echo $truc                    ::= Affiche abcde (Sans spécification d'indice, c'est l'indice 0 d'un tableau qui est pris en compte).
     echo ${truc[1]}               ::= Affiche fghi
     echo ${truc[4]}               ::= Affiche une chaîne vide
     echo ${truc[5]}               ::= Affiche xyz
     echo ${#truc}                 ::= Affiche 5 (le tableau à six éléments de 0 à 5 )
     echo ${truc[@]}               ::= Affiche abcde fghij xyz (les éléments 3 et 4 ne sont pas traités).
     echo ${truc[*]}               ::= Affiche abcde fghij xyz (les éléments 3 et 4 ne sont pas traités).
                                       La différence entre [@] et [*] n'apparaît que pour les interpolations entre "" et en fonction de la variable IFS.
     echo "${truc[@]}"             ::= Affiche la même chose que sans "" 
     echo "${truc[*]}"             ::= Affiche en un seul mot les valeurs du tableau séparées par le premier caractère de la variable IFS.
     echo ${truc[@]}               ::= Affiche abcde fghij xyz (les éléments 3 et 4 ne sont pas traités).
     declare -a truc               ::= Déclaration d'une variable truc de type tableau (voir declare).
     truc=(a b c d)                ::= Initialisation d'un tableau avec quatres indices réspectivement égaux à a,b,d et d.
     truc=({a..z})                 ::= Initialisation d'un tableau avec 26 indices réspectivement égaux à a,b, ... z.
    
    
    




     3.2.6 : VARIABLES STANDARD (PRE-DEFINIES)   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Il existe un certain nombre de variables standard qui sont pré-définies dans des fichiers comme '/etc/profile' ou le '.profile' de chaque utilisateur.

    Il est à noter que ces variables sont pré-définies exportées, mais qu'une modification de contenu n'entraîne pas l'exportation du nouveau contenu.

    Si l'on modifie le contenu et que l'on désire que cette modification suive dans les sous-processus, alors il faut penser à en faire une exportation.

    Les modifications faites dans un '.profile' sont considérées comme permanentes et donc un '.profile' n'est pas obligé de faire une exportation des variables standard qu'il a modifiée, mais il s'agit d'une exception liée à l'interprétation spéciale de ce fichier.

    $HOME : Répertoire standard de l'utilisateur (un 'cd' sans argument se positionne sur ce répertoire)

    $PATH : Suite de répertoires séparés par des ':' et dans lesquels le SHELL cherchera la commande à exécuter. Chaque sous-répertoire défini se termine par ':'. Une suite "::" invoque le répertoire courant comme pourrait le faire ":.:".

    (Voir le paragraphe 'NOTE SUR $PATH') (Voir chapitre 'ETAPES EXECUTION COMMANDE')

    $PS1 : PROMPT principal Texte que le SHELL affiche avant la saisie en mode interactif d'une commande.

    En standard le contenu de 'PS1' est un '$' ou un '#' pour le 'super-utilisateur'.

    $PS2 : PROMPT secondaire Texte que le SHELL affiche avant la saisie en mode interactif d'une structure de commandes ("...", 'if', 'while', etc...) commencée sur une ligne, et non terminée sur cette ligne.

    En standard le contenu de 'PS2' est un '>'. Ce texte apparaît à l'écran lorsque le SHELL considère qu'une commande commencée au niveau 1 ('PS1') n'est pas terminée et attend une suite logique pour être interprétée.

    Exemple : si l'on commence un encadrement de chaîne avec des «'» ou des «"» et que l'on ne termine pas cet encadrement, alors le SHELL passe en niveau 2 en attendant la suite et la fin de l'encadrement.

    Exemple, la commande 'echo "abcd' entraîne une attente de fermeture de l'encadrement «"».

                                 ┌──────────────┐
                                 │ $ echo "abcd │
                                 │ >efgh "      │
                                 └──────────────┘
    

    Même chose pour les structures 'if ...', 'while ...', etc...

    (Voir chapitre SHELL LANGAGE PROGRAMMATION)

    $TERM : Nom du type de terminal.

    D'autre variables sont dynamiques et propres à un processus

    $$ : Numéro de processus

    $? : Code de retour de la dernière commande ou du dernier processus.

    $# : Nombre d'arguments d'appel de la commande.

    $* : Liste des arguments d'appel de la commande sous la forme d'un seul mot "$1 ... $9 ..."

    $@ : Liste des arguments d'appel de la commande sous la forme d'un mot par argument "$1" ... "$9" ...

    Chaque argument sera encadré avec des «"» le contenu subira un marquage par un '\' de certains caractères spéciaux afin de pouvoir ré-utiliser les arguments reçus comme arguments de nouvelles commandes sans qu'ils soient modifiés par une interprétation du SHELL.

    $0 : Nom de la commande telle qu'elle a été appelée par le SHELL.

    $1 : Premier argument.

    $2 : Deuxième argument.

    etc....

    $- : Options d'appel du SHELL courant

    $! : Numéro de processus de la dernière commande lancée en arrière plan.

    NOTES SUR $PATH : Le contenu de $PATH est très important pour la localisation des commandes. Du point de vue performances il est préférable que les sous-répertoires contenant des programmes souvent appelés se trouvent au début de $PATH. Mais le répertoire courant '::' ou ':.:' doit, pour des raisons de sécurité, être en fin de liste.

    En effet si le répertoire courant se trouve en début de liste et que des personnes mal intentionnées ont déposé des 'chevaux de TROIE' dans un répertoire, cela peut avoir des conséquences graves.

    Exemple : Si un script appelé 'cp' se trouve dans un répertoire et contient les instructions 'rm -f $@ 2>/dev/null'. 'cp' est une commande de copie et 'rm' est une commande d'effacement.

    L'utilisateur de la commande 'cp sce dest' détruira le fichier 'sce' et 'dest' sans être averti, si $PATH contient "::" ou ':.:' avant '/bin'.

    Car 'cp' sera recherché dans le répertoire courant avant d'être recherché dans '/usr/bin'.

    Exemple : Si un script baptisé 'su' se trouve dans un répertoire et contient un simulacre de 'su' afin de récupérer le mot de passe dans un fichier et s'auto-détruit après exécution, alors un utilisateur étant dans ce répertoire et voulant utiliser 'su' va composer le mot de passe demandé par 'su', mais ce qu'il compose pourra être détourné dans un fichier par ce script parasite.

    Ce qui est vrai pour le répertoire courant est vrai aussi pour des répertoires où n'importe quel utilisateur peut écrire un script.

    Ceux-ci doivent, pour des raisons de sécurité, être situés dans $PATH derrière les répertoires standard.




     3.3 : SHELL LANGAGE DE PROGRAMMATION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Les chapitres précédents ont traité du SHELL comme interpréteur de commandes, mais le SHELL est aussi un langage de programmation.

    Le fait que le même produit soit utilisé comme interpréteur de commande et langage de programmation fait que l'on peut utiliser les instructions de langage directement comme si l'on saisissait une commande ou alors dans des fichiers LINUX que l'on appellera pour être interprétés.

    Exemple :

    A partir du SHELL interactif Dans un fichier script
      ┌─────────────────────────────┐         ┌────────────────────────────┐
      │ $for fic in toto titi tutu  │         │ for fic in toto titi tutu  │
      │ >do                         │         │ do                         │
      │ >  cat $fic                 │         │   cat $fic                 │
      │ >done                       │         │ done                       │
      └─────────────────────────────┘         └────────────────────────────┘
    

    Dans cet exemple la saisie de Dans cet exemple les instructions la première ligne s'est faite désirées ont été composées sous le 'prompt' de 1er niveau dans un fichier LINUX par un 'PS1' du SHELL. Mais il s'agit éditeur LINUX quelconque.

    d'une instruction nécessitant L'appel de de fichier pourra une structure 'do .... done' le se faire sous SHELL de deux SHELL passe au deuxième niveau manières :

      'PS2' pour la saisie de la suite                ┌────────────┐
      de la structure et lorsque                      │ sh nom_fic │
      le 'done' (correspondant au                     │     ou     │
      premier 'do') aura été validé,                  │   nom_fic  │
      le SHELL exécutera les commandes                └────────────┘
    

    définies dans la structure. Dans le deuxième cas le fichier doit avoir un mode 'x' pour spécifier qu'il s'agit d'un exécutable.

    Dès qu'un programme à réaliser contient un certain nombre d'instructions il est prévisible qu'il aura besoin de test et de mise au point.

    L'utilisation d'un fichier LINUX est évidemment préférable car on peut modifier une instruction et relancer le programme alors que la saisie interactive d'instructions de programmation ne permet pas de sauver ni donc de corriger.




     3.3.1 : REALISATION D'UN SCRIPT SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La réalisation d'un script SHELL est très simple dès que l'on maîtrise un éditeur texte (Voir le chapitre 'EDITEURS TEXTE ed, ex, vi, gvim').

    La syntaxe du langage sera détaillée plus loin mais avant même d'étudier les instructions de programmation il est intéressant de voir qu'un script SHELL peut, sans notion de langage, servir à enchaîner une série de commandes que l'on pourrait composer à chaque fois mais que le script servira à cataloguer.

    Exemple : Tous les soirs on doit lancer une édition des fichiers 'xxx.jal' d'un répertoire '/jal' situé dans la HOME et les remettre à zéro pour préparer une nouvelle journée :

    - Composer un fichier texte 'lp_jal.sh' (l'extension .sh n'est absolument pas obligatoire, mais peut être pratique) contenant ces commandes :

                                    ┌───────────────────┐
                                    │ #!/bin/bash       │  Cette ligne appelée aussi 'sha-bang' permet d'identifier à coup sûr le shell désiré pour l'exécution.
                                    │ cd ~/jal          │  Positionnement sur le répertoire /$HOME/jal
                                    │ for fic in *jal   │  Boucle de traitement des fichiers xxxxx.jal
                                    │ do                │
                                    │   lp $fic         │  Impression de chaque fichier
                                    │   rm $fic         │  Effacement de chaque fichier imprimé
                                    │ done              │
                                    └───────────────────┘
    

    - Remarque sur le 'sha-bang' '#!/bin/bash' : par défaut le shell interprète un fichier n'ayant pas de sha-bang comme un script shell.

    - Remarque sur l'emplacement du fichier le sous répertoire $HOME/bin est l'endroit idéal pour stocker ses propres scripts. En effet le PATH par défaut contient "$HOME/bin".

    - Donner un mode d'exécution au moins 'x' à ce fichier 'chmod +x lp_jal.sh', ou 'chmod 700 lp_jal.sh' etc...

    (Pour plus de détail Voir 'chmod').

    ATTENTION : Un mode '--x' ne suffit pas car un script doit être lisible pour pouvoir être interprété. Donc il doit y avoir au moins 'r-x'. Mais si ce fichier a été créé avec un éditeur, il est vraisemblablement déjà 'rw-' et il suffit d'ajouter 'x'.

    - Il sera possible sous SHELL de lancer la commande './lp_jal.sh' qui, étant considérée exécutable, en raison de son mode 700, sera interprétée par le SHELL.

    Si l'on ne désire pas utiliser le mode 'x' il reste la possibilité de faire interpréter le contenu du fichier par la commande :

            ┌────────────────┐
            │ bash lpjal.sh  │  (Voir le chapitre 'EXECUTION D'UN SCRIPT')
            └────────────────┘
    

    Si on a placé un script dans $HOME/bin (ou dans tout autre répertoire contenu dans PATH), alors on pourra éviter d'appeler ce script avec un chemin complet ou relatif, mais tout simplement par son nom.

            ┌────────────────┐
            │ lpjal.sh       │  Le script sera recherché à partir du contenu de PATH et ceci quelque soit le répertoire courant.
            └────────────────┘
    




     3.3.1.1 : EXECUTION D'UN SCRIPT / APPEL D'UN SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Comme vu précédemment un script SHELL rendu exécutable par un 'chmod' approprié (au moins r-x) s'appelle directement par son nom.

      ┌────────────────┐
      │ $ nom_script   │ Interprétation du script dans un processus fils.
      │ $ . nom_script │ Interprétation du script dans le processus courant.
      └────────────────┘
    

    Si le nom de script est spécifié avec au moins un '/', il est recherché directement, dans le cas contraire il est recherché soit dans la table 'hash' (pour voir s'il a déjà été appelé) soit dans les sous-répertoires contenus dans $PATH et s'il est trouvé dans un de ces sous-répertoires, alors la table 'hash' est mise à jour afin d'éviter une nouvelle recherche lors d'un appel ultérieur de ce script.

    (Voir 'hash' et 'ETAPES EXECUTION COMMANDE').

    Si l'appel a été fait sans '. ' le script sera interprété dans un processus fils, dans le cas contraire il sera interprété dans le processus courant. (Exemple '. .profile' après une modification du fichier '.profile' et pour bénéficier dans l'environnement courant d'une nouvelle exécution du fichier '.profile')

    Mais on peut aussi l'appeler avec la commande 'sh nom_script' et dans ce cas on pourra utiliser des options de 'sh' mais l'exécution se fera toujours dans un processus fils (dans un autre SHELL que le SHELL courant).

    On peut appeler le SHELL pour exécuter un script mais aussi pour modifier provisoirement son environnement et revenir ensuite au SHELL de départ.

    Dans ce cas, il suffit d'appeler la commande 'sh' sans argument.

       ┌───────────────────────────────────────────────┐
       │ sh [-aefhiknrstuvx]                           │  Appel nouveau SHELL
       │ sh [-aefhiknrstuvx] nom_script [arguments]    │  Exécution 'nom_script'
       │ sh -[aefhiknrstuvx]c nom_cde [arguments]      │  Exécution 'nom_cde'
       └───────────────────────────────────────────────┘
    

    Les options a,e,f,h,k,n,t,u,v,x sont celle de 'set' (voir 'set')

    -c cde ::= Les commandes seront lues à partir de la chaîne spécifiée. Cette option doit être la dernière de la liste des options. Et dans ce cas la commande spécifiée peut être autre chose qu'un script SHELL.

    Lorsque la commande spécifiée aura été exécutée, il y aura sortie du processus créé pour l'appel de 'sh' et retour au processus d'origine.

    cde ::= La commande à exécuter lors de cet appel de SHELL.

    Avec une option '-c', il doit toujours y avoir une commande spécifiée, et celle-ci doit être un script exécutable.

    Celle-ci doit être sur une seule ligne. Si la commande doit contenir des espaces ou des tabulations, il faut les encadrer entre «"» ou «'» car l'interprétation s'arrête au premier espace ou à la première tabulation.

    La commande doit être un script devant avoir des droits de lecture et d'exécution.

    -i ::= Le SHELL devient interactif si les entrées/sorties standard sont un clavier/écran.

    Cette option est souvent utilisée dans un programme 'C' devant faire appel à un SHELL interactif en cours d'exécution.

    L'événement 'TERMINATE' est masqué (pas de 'kill -0') L'événement 'INTERRUPT' est intercepté et ignoré , un 'wait' est non interruptif).

    L'événement 'QUIT' est toujours ignoré par le SHELL.

    -r ::= Appel d'un SHELL restreint :

    Pas de possibilité de 'cd'.

    Pas de possibilité de redirection de sortie.

    Pas de possibilité de modification de 'PATH'.

    Pas de possibilité de spécifier un nom de chemin ou de commande contenant un '/'.

    etc...

    -s ::= Les commandes à lire seront lues sur l'entrée standard les arguments éventuels ne définissent que des arguments d'appel ($1, $2, etc...) Exemple : 'sh -s arg1 arg2'.

    Dans ce cas il n'y a pas de nom de script ni de commande spécifié lors de l'appel du SHELL mais le nom du script ou de la commande se définira à partir de l'entrée standard. Les valeurs 'argx' sont évaluables avec $1, $2, etc....




     3.3.1.2 : DEBOGUAGE D'UN SCRIPT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le déboguage d'un script SHELL peut se faire lors de l'appel du SHELL.

      ┌─────────────────────┐
      │ sh [-n] nom_script  │  Interprétation sans exécution
      └─────────────────────┘
    

    La vérification syntaxique sans exécution peut se faire avec l'option '-n'. Dans ce cas les commandes ne sont pas exécutées, mais le SHELL examine toutes les instructions déroulées pendant ce simulacre d'exécution et, si une erreur se produit, il y a affichage du message d'erreur correspondant et abandon de l'interprétation. Mais comme aucune commande (même les commandes syntaxiquement correctes) n'a été exécutée, alors ce traitement n'a pas eu de conséquences comme dans le cas d'un abandon en cours d'exécution réelle.

    Par contre si des commandes utilisent des variables qui sont modifiées par des exécutions, alors le fonctionnement logique n'est pas forcément complètement testé.

                                           ┌─────────────────────┐
                                           │ sh [-v] nom_script  │   Trace lignes source du script
                                           │ sh [-x] nom_script  │   Trace lignes interprétées avec substitution
                                           │ sh [-xv] nom_script │   Les deux traces en même temps
                                           └─────────────────────┘
    

    Exemple avec un script es.sh
                                       ┌──────────────────────────────────┐
                                       │  a=2                             │
                                       │  b=$(($a*5))                     │
                                       │  printf "%2d %2d\n" $a $b        │
                                       └──────────────────────────────────┘
    

               ┌──────────────────────────────────┐     ┌──────────────────────────────────┐       ┌──────────────────────────────────┐
               │   $ bash -v es.sh                │     │   $ bash -x es.sh                │       │   $ bash -vx es.sh               │  
               │   a=2                            │     │   +a=2                           │       │   a=2                            │  
               │   b=$(($a*5))                    │     │   +b=10                          │       │   + a=2                          │  
               │   printf "%2d %2d\n" $a $b       │     │   +printf "%2d %2d\n" 2 10       │       │   b=$(($a*5))                    │
               │    2 10                          │     │    2 10                          │       │   + b=10                         │
               └──────────────────────────────────┘     └──────────────────────────────────┘       │   printf "%2d %2d\n" $a $b       │
                                                                                                   │   + printf '%2d %2d\n' 2 10      │
                                                                                                   │   2 10                           │
                                                                                                   └──────────────────────────────────┘
    

    Ces commandes permettront d'obtenir une trace sur la sortie d'erreur de l'interprétation du script spécifié.

    Pour les autres options de 'sh' voir le chapitre 'EXECUTION D'UN SCRIPT' ou 'APPEL SHELL'.

    On peut aussi inclure ces options aux endroits désirés dans le script SHELL (de façon à n'avoir une trace qu'aux endroits intéressants) :

      ┌────────────────────────────────────┐
      │ instructions ..................    │
      │ set -x    pour activer la trace    │  ou 'set -xv' ou encore 'set -v'
      │ instructions ..................    │
      │ set +x    pour désactiver la trace │  ou 'set +xv' ou encore 'set +v'
      │ instructions ..................    │
      └────────────────────────────────────┘
    

    Pour les autres options de 'set' voir le chapitre 'set'.




     3.3.1.3 : EXEMPLES D'APPELS DE SCRIPT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Afin de visualiser l'effet d'exportation des variables et d'appel de script, nous supposons qu'un 'script' appelé 'toto' contient :

                          ┌─────────────┐
                          │ echo $VAR1  │
                          │ echo $VAR2  │
                          │ VAR3=var3   │
                          │ export VAR3 │
                          │ VAR4=var4   │
                          │ echo $VAR4  │
                          └─────────────┘
    

    Avant d'appeler le script de trois façons différentes la variable 'VAR1' est initialisée et exportée, 'VAR2' est seulement initialisée.

    De plus le script initialise une variable 'VAR3' et une variable 'VAR4' et exporte uniquement 'VAR3'.

    Après exécution on affiche le contenu de 'VAR3' et 'VAR4'.

       ┌─────────────────────┬───────────────────────┬────────────────────────┐
       │ Appel d'un script   │    Appel d'un script  │    Appel d'un script   │
       │ exécutable par son  │    exécutable ou non  │    exécutable ou non   │
       │ nom :               │    avec 'sh nom'      │    avec '. nom' :      │
       ├─────────────────────┼───────────────────────┼────────────────────────┤
       │ $ VAR1=var1         │    $ VAR1=var1        │    $ VAR1=var1         │
       │ $ export VAR1       │    $ export VAR1      │    $ export VAR1       │
       │ $ VAR2=var2         │    $ VAR2=var2        │    $ VAR2=var2         │
       │ $ toto              │    $ sh toto          │    $ . toto            │
       │ $ echo "--------"   │    $ echo "--------"  │    $ echo "--------"   │
       │ $ echo $VAR3        │    $ echo $VAR3       │    $ echo $VAR3        │
       │ $ echo $VAR4        │    $ echo $VAR4       │    $ echo $VAR4        │
       ├─────────────────────┼───────────────────────┼────────────────────────┤
       │ Résultat écran      │    Résultat écran     │    Résultat écran      │
       ├─────────────────────┼───────────────────────┼────────────────────────┤
       │ var1                │    var1               │    var1                │
       │                     │                       │    var2                │
       │ var3                │    var3               │    var3                │
       │ var4                │    var4               │    var4                │
       │ --------            │    --------           │    --------            │
       │                     │                       │    var3                │
       │                     │                       │    var4                │
       └─────────────────────┴───────────────────────┴────────────────────────┘
    

    Dans les deux premiers cas, l'exécution s'est faite dans un processus 'fils' qui a hérité de l'environnement exportable du 'père'. Mais les variables qu'il initialise, exportées ou non, ne remontent pas au processus 'père'.

    Dans le troisième cas, l'exécution s'est faite dans le même processus avec accès au même environnement.




     3.3.2 : COMMANDES INTERNES DU SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre est consacré aux commande internes du SHELL. Il ne s'agit pas de la documentation détaillée de ces commandes, mais d'un simple résumé.

    Pour plus de détails voir le chapitre COMMANDES INTERNES DU SHELL du manuel bash.




     3.3.2.1 : cd  CHANGEMENT REPERTOIRE DE TRAVAIL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌─────────────────────────────────────────────────────────────────┐
        │ cd ::= Changement de répertoire de travail (répertoire courant) │
        └─────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌────────────────────────┐
        │ cd [ nom_répertoire ]  │
        └────────────────────────┘
    

    DESCRIPTION La commande 'cd' permet de se positionner sur le répertoire spécifié en argument. Celui-ci devient le nouveau répertoire courant.

    En absence de répertoire spécifié, 'cd' se positionne sur le contenu de $HOME.

    Si le répertoire spécifié commence par un "/" un "." ou ".." ce répertoire est recherché directement sans examiner le contenu de la variable 'CDPATH'. On parle de spécification absolue ou relative.

           Répertoire absolu (/xxx/yyy/zzz) ou relatif (../xxx/yyy)
                /  ::= Racine de base
                .  ::= répertoire courant
                .. ::= Répertoire père du répertoire courant
    

    Dans les autres cas 'cd' essaie de trouver le répertoire spécifié relativement au contenu de la variable '$CDPATH'.

    Si '$CDPATH' est vide ou non défini, alors la recherche se fait à partir du répertoire courant.

    Le contenu de '$CDPATH' est syntaxiquement et sémantiquement le même que pour '$PATH':

          -  Recherche de la gauche vers la droite dans les différents
               répertoires séparés par un ':'.
          -  Un '::' spécifie le répertoire courant.
    

    Si le répertoire a été trouvé dans un des répertoires contenus dans 'CDPATH', alors il y a affichage sur la sortie standard de celui-ci
                   ┌────────────────┐      ┌────────────────┐
         Exemple : │ CDPATH=/:/home │      │ CDPATH=/home:/ │
                   │ cd bin         │      │ cd bin         │
                   │ /bin           │      │ /home/bin      │
                   └────────────────┘      └────────────────┘
    

    Dans tous les cas le répertoire à atteindre doit être accessible à l'utilisateur ( droit d'accès 'd--x--x--x' au minimum pour lui ainsi que chacun de ses pères (voir 'chmod (1)) ).

    La commande 'cd' est une commande interne du SHELL qui est exécutée dans le processus courant.

    VOIR AUSSI
       ┌──────────────────┐
       │ pwd(1)           │
       └──────────────────┘
    

    Pour plus de détails voir la commande cd dans le manuel bash.

    EXEMPLES

     ┌─────────────────────────────────────────────────────────────────────────────┐
     │ cd $HOME            ::=   cd                                                │ 
     │ cd ..               ::=   Retour au répertoire précédent (père)             │ 
     │ cd /u*/application  ::=   Passage au répertoire 'application' contenu       │ 
     │                           dans le premier répertoire /u0 , /u1 , etc...     │ 
     │                           qui contient un répertoire 'application'.         │ 
     │ cd /*/*/*/spdir     ::=   Passage à un répertoire 'spdir' contenu dans      │ 
     │                           un quatrième niveau de sous-répertoires sans      │ 
     │                           précision du file-system ni des deux niveaux      │ 
     │                           intermédiaires. Cette méthode peut être très      │ 
     │                           lente car il y a recherche dans tous les          │ 
     │                           répertoires du système.                           │ 
     └─────────────────────────────────────────────────────────────────────────────┘
    

    Si la variable 'CDPATH' est définie, elle sert à rechercher un répertoire de la même façon que l'on recherche unexécutable à partir de PATH.

    Exemple avec CDPATH=~:/: (Le caractère ~ (tilde) sera interpolé comme $HOME).

       ┌────────────────┐
       │ cd tmp         │  S'il existe un répertoire tmp dans la HOME de l'utilisateur, c'est ce répertoire qui sera choisi grâce à CDPATH
       │ /home/pma/tmp  │  Dans le cas contraire, c'est /tmp qui sera choisi.
       └────────────────┘
    

    Positionnement en absolu ou en relatif, donc indépendant du contenu de '$CDPATH' :

       ┌──────────────────┐
       │ cd /tmp          │
       │ pwd              │
       │ /tmp             │
       └──────────────────┘
    




     3.3.2.2 : declare,typeset DECLARATION EXPLICITE DE VARIABLES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le SHELL n'a pas besoin de déclaration explicite de variable, toute variable non déclarée est considérée comme de type alphanumérique.

    Les instructions internes declare ou typeset permettent de faire des déclarations explicites

    SYNOPSIS
    declare [-afFirtx] [-p] [nom[=valeur] ...]
    typeset [-afFirtx] [-p] [nom[=valeur] ...]
    
         -a     ::= Tableau (array)
         -f     ::= Fonction (fonction)
         -F     ::= Liste des Fonctions sans leut contenu
         -i     ::= Entier (integer)
         -r     ::= lecture seulement (readonly)
         -t     ::= Attribut trace uniquement pour les focntions (sans effet sur une variable)
         -x     ::= Exportation (voir aussi export) 
    
    
    Une déclaration de variable de type entier entraîne une affectation à zéro si la valeur n'est pas numérique, et tronquée si la
    valeur contient des décimales.
    
    

    Exemples de déclaration de variable
       declare -a nom_tableau       ::= Déclaration de type tableau
       declare -i nom_variable      ::= Déclaration de type entier
       declare -r nom_variable      ::= Déclaration de type 'readonly', à utiliser après initialisation à la valeur désirée ou
                                        utiliser 'declare -r nom_variable=valeur'.
    
    Exemples d'autres utilisations de declare
       declare                      ::= Affiche toutes les variables, fonctions, (déclarées ou non) et leurs contenu.
       declare -a                   ::= Affiche toutes les variables de type tableau et le contenu de chaque indice.
       declare -i                   ::= Affiche toutes les variables de type integer et leut contenu.
       declare -r                   ::= Affiche toutes les variables de type readonly.
       declare -x                   ::= Affiche toutes les variables exportées.
       declare -f                   ::= Affiche toutes les noms de fontions (avec leur contenu).
       declare -F                   ::= Affiche toutes les noms de fontions (sans leur contenu).
    
    




     3.3.2.3 : echo  AFFICHAGE MOTS/TEXTE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
       ┌─────────────────────────────────┐
       │ echo ::=  Affichage d'arguments │
       └─────────────────────────────────┘
    

    SYNOPSIS
       ┌──────────────────────────┐
       │ echo [ arg ] ...         │
       │ echo [ options] [ arg ]  │ 
       └──────────────────────────┘
    

    DESCRIPTION La commande 'echo' est une commande interne du SHELL qui écrit sur la sortie standard chaque argument spécifié (séparé par un espace) et écrit après le dernier argument un caractère 'LF' de passage à une nouvelle ligne (sauf utilisation du '\c').

    Pour gérer des caractères spéciaux, la version standard de SHELL '/usr/bin/sh' interprète les caractères suivants :

           ┌────────────────────────────────────────────────────────────────────┐
           │  \a     BELL Caractère (ALERT) sonette                             │
           │  \b     BS   Retour en arrière d'un caractère                      │
           │  \c          Suppression du passage à la ligne implicite           │
           │               (doit normalement être le dernier caractère          │
           │               et de toute façon les suivants sont ignorés).        │
           │  \f     FF   Saut de page                                          │
           │  \n     LF   Passage à la ligne suivante                           │
           │  \r     CR   Retour en début de ligne                              │
           │  \t     TAB  Tabulation horizontale                                │
           │  \v     VTAB Tabulation verticale                                  │
           │  \\          backslash                                             │
           │  \0ooo       Où 'ooo' est une valeur octale représentant le        │
           │                caractère désiré sur 1, 2 ou 3 caractères octaux.   │
           │              Exemple :  "\07" = sonnette.                          │
           │  \xhh        Où 'hh' est une valeur hexadécimale représentant le   │
           │                caractère désiré .                                  │
           │              Exemple :  "\x07" = sonnette                          │
           └────────────────────────────────────────────────────────────────────┘
    

    ATTENTION : L'utilisation du 'backslash' '\' sous SHELL doit tenir compte de l'utilisation que fait le SHELL de ce caractère avant d'exécuter réellement la commande.

    Comme pour toute commande, les arguments sont traités par le SHELL avant exécution de la commande. L'utilisation de caractères spéciaux avec ou sans encadrement par «'» ou «"» suit les règles standard.

    OPTIONS :

    -n ::= Ne pas ajouter de retour à la ligne implicite en fin d'affichage.

    -e ::= Interpréter les caractères spéciaux \a, \b, ....

    -E ::= Ne pas interpréter les caractères spéciaux \a, \b, .... C'est l'option par défaut de echo'.



    AFFICHAGE SUR SORTIE ERREUR La commande 'echo' affiche les arguments sur la sortie standard, mais on peut utiliser une redirection '>&2' si l'on désire afficher ces arguments sur la sortie d'erreur.

         ┌────────────────────────────────┐
         │ echo "Fichier introuvable" >&2 │
         └────────────────────────────────┘
    

    Dans un script (dont la sortie d'erreur a pu être redirigée), cette commande affichera le message sur la sortie standard de ce script.



    EXEMPLES

      ┌──────────────────┐        ┌───────────────────┐          ┌────────────┐
      │ echo abcdefgh    │   ::=  │ echo "abcdefgh"   │  Affiche │ abcdefgh   │    Affichage simple d'un argument                                   
      └──────────────────┘        └───────────────────┘          └────────────┘
    

      ┌─────────────────────┐             ┌─────────────┐    
      │ echo abcd   efgh    │ ::= Affiche │ abcd efgh   │   Les espaces surnuméraires ont été supprimés par le SHELL
      └─────────────────────┘             └─────────────┘   La commande echo a reçu deux arguments séparés. 
    

      ┌───────────────────────┐             ┌───────────────┐    
      │ echo "abcd   efgh"    │ ::= Affiche │ abcd   efgh   │   Les espaces surnuméraires encadrés avec des "" ont été conservés par le SHELL. (echo n'a reçu qu'un seul argument.
      └───────────────────────┘             └───────────────┘   La commande echo n'a reçu qu'un seul argument.
    

      ┌──────────────────┐        ┌───────────────────┐          ┌────────────┐
      │ echo abcd\\nefgh │   ::=  │ echo "abcd\nefgh" │  Affiche │ abcd\nefgh │    Le \n n'est pas interprété par echo comme un passage à la ligne.
      └──────────────────┘        └───────────────────┘          └────────────┘
    

      ┌─────────────────────┐        ┌──────────────────────┐          ┌──────┐
      │ echo -e abcd\\nefgh │   ::=  │ echo -e "abcd\nefgh" │  Affiche │ abcd │    Le \n est interprété par echo comme un passage à la ligne.
      └─────────────────────┘        └──────────────────────┘          │ efgh │
                                                                       └──────┘
      ┌────────────┐      ┌──────────────┐          ┌─────────────────────┐
      │ echo $PATH │  ::= │ echo "$PATH" │  Affiche │ le contenu de $PATH │
      └────────────┘      └──────────────┘          └─────────────────────┘
    

      ┌─────────────┐     ┌───────────────┐     ┌──────────────┐         ┌─────┐
      │ echo \$PATH │ ::= │ echo "\$PATH" │ ::= │ echo '$PATH' │ Affiche │$PATH│
      └─────────────┘     └───────────────┘     └──────────────┘         └─────┘
    

    Dans ces trois cas le '$' n'a pas été traité par le SHELL comme désignant une substitution de nom de variable par son contenu.

      ┌──────────────┐     ┌───────────────┐     ┌───────────────┐
      │ echo -e \\07 │ ::= │ echo -e "\07" │ ::= │ echo -e '\07' │  Fait sonner le
      └──────────────┘     └───────────────┘     └───────────────┘    terminal
    

      ┌───────────────┐     ┌────────────────┐     ┌────────────────┐
      │ echo -e \\x07 │ ::= │ echo -e "\x07" │ ::= │ echo -e '\x07' │  Fait sonner le
      └───────────────┘     └────────────────┘     └────────────────┘    terminal
    

      ┌───────────────┐     ┌────────────────┐     ┌─────────────────┐
      │ echo -e "\07" │ ::= │ echo -e "\007" │ ::= │ echo -e "\0007" │  Equivalence des valeurs 
      └───────────────┘     └────────────────┘     └─────────────────┘  octales avec pré-zéros.
    

      ┌─────-──────────┐      ┌─────-──────────┐
      │ echo -e "\071" │ ::=  │ echo -e "\x39" │   ::= Affiche un '9' (En ASCII '9'::='\0x39'::='\071')
      └────────────────┘      └────────────────┘ 
    

      ┌──────────────────┐      ┌──────────────────┐
      │ echo -e "\00071" │ ::=  │ echo -e "\x071"  │Fait sonner le terminal et affiche un '1', car la valeur octale est interprétée au maximum sur les
      └──────────────────┘      └──────────────────┘  trois positions qui suivent le premier '0' et la valeur hexadécimale sur deux caractères.
    

      ┌───────────────────┐
      │ echo coucou >toto │  ::= Création d'un fichier 'toto' contenant
      └───────────────────┘        la chaîne 'coucou' et un 'LF' (implicite).
    

    Exemple d'utilisation du méta-caractère '\c' avec un script qui devrait afficher un texte invitant à saisir un nom de fichier avant d'exécuter cette saisie :

      ┌─────────────────────────────────────────┐
      │ echo "Nom de fichier : " ; read nom_fic │ Affichage du texte et saisie du nom de fichier sur la ligne suivante ('LF' implicite).
      └─────────────────────────────────────────┘
    

      ┌──────────────────────────────────────────────┐
      │ echo -e "Nom de fichier : \c" ; read nom_fic │ Affichage du texte et saisie du nom de fichier sur la même ligne
      └──────────────────────────────────────────────┘
    




     3.3.2.4 : eval  EVALUATION LIGNE DE COMMANDE+EXECUTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ eval  ::=  Evaluation d'arguments et exécution de ces arguments évalués │
     │              comme s'il s'agissait d'une ligne de commande(s).          │
     └─────────────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
      ┌────────────────┐
      │ eval arg1 .... │
      └────────────────┘
    

    Chaque argument doit être séparé des autres par au moins un espace ou une tabulation.

    Le dernier argument doit être suivi d'un séparateur de commandes ';' ou passage à la ligne.

    DESCRIPTION

    La substitution, dans une ligne de commande, des variables d'environnement par leurs valeurs peut poser certains problèmes dus aux étapes successives suivies par le SHELL pour interpréter une ligne de commandes.

    (Pour plus de détails voir auparavant le chapitre 'ETAPES EXECUTION COMMANDE').

    En effet dans un cas simple on a le droit d'affecter à une variable le nom d'une commande :

        ┌───────────────┐
        │ $ cde='who'   │   Affectation de 'who' dans la variable 'cde'
        │ $ $cde        │   Appel de 'who' par l'intermédiaire de $cde.
        └───────────────┘
    

    Le résultat est correct, on obtient bien le résultat de 'who'.

    Mais si la commande que l'on désire affecter à une variable est un groupe de commandes simples séparées par des ';'.

        ┌────────────────────┐
        │ $ cde='who ; date' │    Exécution uniquement de 'who'
        │ $ $cde             │
        └────────────────────┘
    

    Le résultat n'est pas correct car on n'obtient que l'exécution de 'who' et le ';' ou 'date' ont été pris comme arguments de 'who' qui les a ignorés car 'who' ne traite comme arguments que 'am i' et ne fait pas d'erreur pour des arguments qu'il ne traitera pas.

    Autres exemples de problème lié aux étapes d'interprétation.

        ┌──────────────────┐
        │ $ cde='who;date' │      Message 'who;date : not found'
        │ $ $cde           │
        └──────────────────┘
    

    Le résultat est incorrect car le SHELL croit devoir lancer une commande 'who;date'.

    Ces deux problèmes sont dus au fait que la substitution des variables d'environnement par leur contenu (Etape 4) est effectuée après l'étape qui recherche les séparateurs de commandes dans une ligne de commandes (Etape 1).

    Le ';' apparaît dans ce cas trop tard pour être interprété par le SHELL comme séparateur de commande.

    La commande interne 'eval' permet de demander au SHELL une première interprétation de la ligne de commande avant de la faire exécuter par le SHELL proprement dit.

     ┌────────────────────┐      ┌──────────────────┐
     │ $ cde='who ; date' │ ::=  │ $ cde='who;date' │  Il y aura bien exécution
     │ $ eval $cde        │      │ $ eval $cde      │  de 'who' et de 'date'.
     └────────────────────┘      └──────────────────┘
    

    EXEMPLES

    Le cas précédent est déjà un bon exemple d'utilisation de 'eval'.

    Un autre problème peut se poser avec des variables d'environnement qui doivent pointer sur d'autres variables d'environnement.

       ┌──────────────┐
       │ titi=coucou  │  ::= Affectation de 'coucou' dans 'titi'
       │ toto='$titi' │  ::= Affectation de '$titi' dans 'toto'
       └──────────────┘      (sans substitution puisqu'on utilise des «'»)
    

       ┌────────────────────────────────────┐
       │ echo $toto      ::= Affiche '$titi'│
       └────────────────────────────────────┘
    

    (Substitution d'une variable par l'étape 4 des 'ETAPES EXECUTION COMMANDE') Alors que :

       ┌──────────────────────────────────────┐
       │ eval echo $toto ::= Affiche 'coucou' │
       └──────────────────────────────────────┘
    

    Dans ce dernier cas, 'eval' a substitué '$toto' par son contenu '$titi' et a demandé au SHELL d'exécuter 'echo $titi' le SHELL a donc maintenant substitué 'coucou' à '$titi' et 'echo' a affiché 'coucou'.

    Les différents traitements peuvent être visualisés si l'on utilise les options de traces '-xv' du SHELL. (Voir 'set' ou 'DEBOGUAGE SCRIPT')

        ┌── Script essai ──┐      ┌── Exécution de 'sh -xv essai' ─┐
        │ titi=coucou      │      │ titi=coucou                    │
        │ toto='$titi'     │      │ titi=coucou                    │
        │ echo $toto       │      │ toto='$titi'                   │
        │ eval echo $toto  │      │ toto=$titi                     │
        └──────────────────┘      │ echo $toto                     │
                                  │ + echo $titi                   │
                                  │ eval echo $toto                │
                                  │ + eval echo $titi              │
                                  │ + echo coucou                  │
                                  └────────────────────────────────┘
    




     3.3.2.5 : exit  SORTIE AVEC/SANS CODE RETOUR   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌───────────────────────────────────────────────────────┐
        │ exit ::=  Sortie script/processus avec code de retour │
        └───────────────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌──────────────────────┐
        │ exit [ code_retour ] │
        └──────────────────────┘
    

    DESCRIPTION La commande interne 'exit' permet de sortir du processus ou du script en cours avec positionnement du code de retour spécifié.

    Si l'on était sous le prompt du SHELL on termine la session de SHELL avec retour au login, si celle-ci était le processus de base. Ceci est donc équivalent à 'CTRL+D'.

    Dans un script (interprété par le SHELL dans un processus) on arrête l'interprétation et l'on quitte le processus.

          ┌───────────────────┐
          │ exit              │
          │ exit 0            │
          │ exit 1            │
          │ exit $CODE_RETOUR │
          └───────────────────┘
    

    Les codes de retour utilisables sous SHELL sont des entiers positifs compris entre 0 et 255.

    Par convention :

          ┌───┐
          │ 0 │     ::= Commande exécutée normalement.
          └───┘
     ┌───────────┐
     │ Valeur >0 │  ::= Commande non exécutée correctement.
     └───────────┘
    

    Le code de retour peut être évalué avec la variable d'environnement '$?'.




     3.3.2.6 : export EXPORTATION VARIABLE ENVIRONNEMENT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Les variables d'environnement positionnées dans un processus appartiennent à ce processus, mais pour permettre aux processus 'fils' d'en hériter, il faudra utiliser la commande 'export' (sauf si l'option 'set -a' a été positionnée car dans ce cas l'affectation de toute nouvelle variable entraîne son exportation implicite (voir 'set')).

    Exemple d'exportation explicite:

                    ┌─────────────────┐          ┌────────────────────────┐
                    │  nombre=123     │          │  export nombre=123     │
                    │  export nombre  │          └────────────────────────┘
                    └─────────────────┘          
    

       ┌─────────────────────┐
       │ export nom_variable │     ::=  Exportation de la variable dans les processus fils.
       └─────────────────────┘          
    

       ┌────────┐
       │ export │                  ::=  Sans argument spécifié la commande 'export' affiche
       └────────┘                       la liste des variables déjà traitées par 'export'.
    




     3.3.2.7 : history HISTORIQUE DES COMMANDES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La commande history permet d'afficher l'historique des commandes déjà exécutées.

         history [n]
         history -c
         history -d offset
         history -anrw [fichier]
         history -p arg [argument ...]
         history -s arg [argument ...]
    

    Sans options, affiche la liste des commandes de l'historique, avec des numéros de ligne. Les lignes marquées avec un astérisque * ont été modifiées. Un argument n permet de ne lister que les n dernières lignes. Si la variable shell HISTTIMEFORMAT existe et n'est pas vide, elle est utilisée comme une chaîne de format pour strftime(3) afin d'afficher l'horodatage associé à chaque entrée de l'historique affichée. Il n'y aura pas d'espace entre l'horadatage ainsi formaté et la ligne de l'historique. Si un argument est fourni, il est utilisé comme nom de fichier historique, sinon on utilise la valeur de la variable HISTFILE Les options ont les significations suivantes :

    -a Ajouter les « nouvelles » lignes d'historiques (celles créées depuis le début de la session actuelle de bash) dans le fichier.

    -n Lire dans le fichier, et ajouter à la liste d'historique, les lignes non encore lues. Il s'agit des lignes qui ont été ajoutées dans le fichier depuis le début de la session actuelle de bash.

    -r Lire le contenu du fichier, et l'utiliser comme historique courant.

    -w Écrire dans le fichier l'historique actuel, en écrasant le contenu precedent.

    -c Effacer le fichier d'historique en détruisant toutes ses entrées.

    -p Effectuer la substitution sur les arguments suivants, et afficher le résultat sur la sortie standard. Ne pas mémoriser les résultats dans la liste d'historique. Chaque argument doit être protégé pour éviter le développement normal.

    -s Enregistrer les arguments dans la liste d'historique comme entrée unique. La dernière commande de la liste d'historique est supprimée avant que les arguments soient ajoutés.

    Si la variable HISTTIMEFORMAT existe, l'information d'horodatage associée à chaque entrée de l'historique est écrite dans le fichier d'historique. La valeur de retour est 0, sauf si une option illégale est fournie, ou si une erreur se produit durant la lecture ou l'écriture du fichier, si une valeur d'offset non valide est fournie comme argument à -d, ou si le développement de l'historique fourni à -p échoue.

    Pour pouvoir utiliser l'historique, avec ou sans recherche de motif, voir <CTRL><R>, <CTRL><P> dans le chapitre MANIPULATIONS CLAVIER.




     3.3.2.8 : pwd  NOM DU REPERTOIRE COURANT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
       ┌────────────────────────────────────────────────┐
       │ pwd ::= Affichage du nom du répertoire courant │
       └────────────────────────────────────────────────┘
    

    SYNOPSIS
       ┌─────┐
       │ pwd │
       └─────┘
    

    DESCRIPTION

    La commande 'pwd' affiche le nom du répertoire courant

    Si un utilisateur 'dupond' se trouve dans son répertoire de base ($HOME)

          ┌─────┐           ┌──────────────┐
          │ pwd │  Affiche  │ /home/dupond │
          └─────┘           └──────────────┘
    

    VOIR AUSSI
       ┌───────┐
       │ cd(1) │
       └───────┘
    

    DIAGNOSTICS

    "Cannot open .." ou "Read error in .." lors de la commande indique un incident grave et doit être signalé au responsable du système.

    NOTES

    Si le répertoire courant ou un de ses pères a été modifié il se peut que 'pwd' ne puisse plus donner d'information correcte.

    Le mieux est de se repositionner dans le répertoire désiré avec un path absolu pour corriger le problème.




     3.3.2.9 : set ENVIRONNEMENT SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

      ┌─────────────────────────────────┐
      │ set [--aefhkntuvx [arguments]]  │
      └─────────────────────────────────┘
    

    La commande 'set' permet de positionner des variables ou des paramètres d'environnement du SHELL courant.

    OPTIONS :

    -- ::= Ne modifie aucune option mais permet d'affecter $1 avec la valeur '-'.

    Les autres options peuvent être spécifiées avec un '-' ou un '+' selon que l'on active ou désactive l'option désirée. Ainsi '+a' voudra dire que l'on désactive l'option '-a'.

    -a ::= Marquage des variables modifiées ou créées afin de les exporter automatiquement.

    -e ::= Exécution du SHELL interrompue si une commande contenue dans ce SHELL se termine avec un code de retour différent de 0.

    -f ::= Invalide la substitution des méta-caractères (?,*,[...],...) pour la génération de noms de fichiers.

    -h ::= Permet de mémoriser une commande, spécifiée lors de la définition d'une fonction, dans la table 'hash' lors de cette définition et non pas lors de la première exécution.

    -k ::= Les arguments qui correspondent syntaxiquement à des affectations de variable sont exécutés même s'ils ne sont pas placés avant le début de la commande elle-même.

    (Voir 'ETAPES EXECUTIONS DE COMMANDES') Exemple : echo a=b c ::= Affiche a=b c

    set -k echo a=b c ::= Exécute 'a=b' et affiche c.

    -n ::= Lire les commandes sans les exécuter L'étape 10 (Voir 'ETAPES EXECUTION COMMANDE' est ignorée.

    Cette option permet de tester la syntaxe d'un script.

    -t ::= Arrêt du SHELL dès la lecture et l'exécution de la première commande.

    Si cette option est utilisée lors de l'appel de 'sh' sans nom de script, alors le SHELL attend une ligne de commande sans afficher de prompt et sortira du processus dès la fin de cette commande.

    -u ::= Considérer que l'utilisation d'une variable non définie est une erreur affichant : 'nom_var : parameter not set'.

    Si cette erreur est rencontrée, alors il y a abandon de l'exécution avec un code retour différent de 0.

    -v ::= Affichage des lignes, par le SHELL, telles qu'elles sont lues. Il s'agit d'une trace du script source.

    -x ::= Affichage sur la sortie standard d'erreur des lignes, et de leurs arguments, telles qu'elles sont exécutées (avec substitution des variables, des méta-caractères et des commandes encadrées avec '`' par leurs valeurs).

    Il s'agit d'une trace d'exécution du script.

    L'option '-xv' est souvent intéressante pour voir ce que le SHELL a interprété à partir de chaque commande contenue dans le script.

    ARGUMENTS :

    Si l'on spécifie des arguments, ils sont affectés dans les variables '$1', '$2', ... '$9', '$10', ... ' et de toute façon l'ensemble est affecté à '$*' ou '@'. La variable '$#' reçoit le nombre d'arguments spécifiés. On positionne ainsi les variables d'appel standard mais ceci en cours d'exécution.

    Si l'on ne spécifie pas d'arguments ces variables standard restent inchangées et gardent leurs valeurs d'origine.

       Exemple : ┌────────────────────────────────────────┐
                 │ set t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 │
                 │ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11│
                 │ echo $@                                │
                 │ echo $*                                │
                 └────────────────────────────────────────┘
    

    Affiche
                 ┌────────────────────────────────────┐
                 │ t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 │
                 │ t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 │
                 │ t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 │
                 └────────────────────────────────────┘
    

    Il existe une différence entre $* et $@, mais celle ci ne se voit que lors d'une interpolation entre doubles quotes.

       Exemple : ┌────────────────────────────────────────┐
                 │ set t1 t2 t3                           │
                 └────────────────────────────────────────┘
                 ┌────────────────────────────────────────┐  ┌────────────────────────────────────────┐
                 │  $ for i in $* ; do echo $i ; done     │  │  $ for i in $@ ; do echo $i ; done     │
                 │  t1                                    │  │  t1                                    │
                 │  t2                                    │  │  t2                                    │
                 │  t3                                    │  │  t3                                    │
                 └────────────────────────────────────────┘  └────────────────────────────────────────┘
    

                 ┌────────────────────────────────────────┐  ┌────────────────────────────────────────┐
                 │  $ for i in "$*" ; do echo $i ; done   │  │  $ for i in "$@" ; do echo $i ; done   │
                 │  t1 t2 t3                              │  │  t1                                    │
                 │                                        │  │  t2                                    │
                 │                                        │  │  t3                                    │
                 └────────────────────────────────────────┘  └────────────────────────────────────────┘
    

    Exemple d'utilisation de set avec une commande composée.

     ┌───────────────────────┐             ┌─────────────────┐
     │ set -- $(ls -l toto)  │  Affiche    │ toto -rwxrwxrwx │
     │ echo $9 $1            │             └─────────────────┘
     └───────────────────────┘
    

    A noter l'option '--' qui permet de recevoir le premier argument de 'ls' qui peut commencer par un '-' comme un argument et non pas comme une option.

    On affiche le neuvième et le premier argument donc le nom et le mode.




     3.3.3 : INSTRUCTIONS DE PROGRAMMATION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Par rapport aux chapitres précédents où les scripts n'étaient que des empilements de commandes, les instructions de programmation permettront de faire des traitements conditionnels (tests) et de définir des boucles (ce qui est le propre d'un langage structuré).

    Ces instructions sont vues dans le cadre de scripts, mais elles peuvent aussi être utilisées sous forme de commande SHELL à partir du prompt, de même que dans un script on peut utiliser les commandes standard et non pas uniquement des instructions de base.

    Comme il s'agit d'un langage interprété à syntaxe très libre il faudra veiller à la lisibilité (Décalage vers la droite des instructions contenues dans une structure 'if ..... fi' ou 'do ..... done' etc...).

    Dans ce chapitre sont regroupées des commandes internes ou externes qui sans être des instructions de programmation sont étroitement liées à la programmation et que l'on trouvera plus souvent dans les scripts qu'en utilisation sous le prompt du SHELL.

     ┌───── Commandes liées à la programmation  ────────┬── Type de commande ─┐
     │ Décalage arguments d'appel   ::= 'shift'         │   Commande interne  │
     │                                                  │                     │
     │ Analyse des options d'appel  ::= 'getopts'       │   Commande interne  │
     │                                                  │                     │
     │ Sortie avec/sans code_retour ::= 'exit n'        │   Commande interne  │
     │                                                  │                     │
     │ Saisie d'information         ::= 'read ... '     │   Commande interne  │
     │                                                  │                     │
     │ Masquage de signaux          ::= 'trap'          │   Commande interne  │
     │                                                  │                     │
     │ Exécution commande dans      ::= 'exec'          │   Commande interne  │
     │ le même processus.                               │                     │
     │                                                  │                     │
     │ Test divers                  ::= 'test -. arg'   │   Commande interne  │
     │                                                  │                     │
     │ Expression arith./logique    ::= 'expr ...... '  │   Commande externe  │
     └──────────────────────────────────────────────────┴─────────────────────┘
    

     ┌────────── Instructions de débranchements ou de boucles ─────────────────┐
     │ Instruction conditionnelle ::= 'if ... then ... [elif...] [else...] fi' │
     │                                                                         │
     │ Exécution conditionnelle   ::= 'case .... in ........ esac'             │
     │                                                                         │
     │ Test divers                ::= 'test -. nom_nomficher'                  │
     │                                                                         │
     │ Boucle for                 ::= 'for ... in ... do ... done'             │
     │                                                                         │
     │ Boucle while               ::= 'while .... do ...... done'              │
     │                                                                         │
     │ Boucle until               ::= 'until .... do ...... done'              │
     │                                                                         │
     │ Sortie boucle              ::= 'break'                                  │
     │                                                                         │
     │ Saut => fin boucle         ::= 'continue'                               │
     └─────────────────────────────────────────────────────────────────────────┘
    

    Il est à noter que ces instructions deviennent plus ou moins des mots-clés du SHELL.

    Dans d'autres langages on parelearit de mots clés inutilisables en dehors du contexte de mot-clé.

    Mais en fait le SHELL interprète seulement le premier mot de chaque commande comme étant soit une commande (interne ou externe), soit une instruction (Voir le chapitre 'ETAPES EXECUTION COMMANDE').

    Derrière ce premier mot, on trouve les arguments de la commande (ou de l'instruction).

    Pour ces arguments il n'y a pas de contrainte de nommage, et l'on peut, même si cela n'est pas recommandé, utiliser des noms de commande (ou d'instructions). On peut donc avoir une variable qui s'appelle 'for' mais cela ne facilite peut-être pas la relecture.

    Exemples :

         ┌──────────────────┐   ┌─────────────────┐  Ces deux boucles sont
         │ for for in 1 2 3 │   │ for in in 1 2 3 │  syntaxiquement correctes
         │  do              │   │  do             │  et fonctionnent, mais il
         │    echo $for     │   │    echo $in     │  aurait mieux valu utiliser
         │ done             │   │ done            │  d'autres noms de variable.
         └──────────────────┘   └─────────────────┘
    

    Pour l'emplacement des mots-clés, ceux-ci doivent être soit en début de ligne, soit séparés des précédents par un séparateur de commandes.

    Pour des raisons de lisibilités le retour à la ligne sera souvent préférable :

                                                  ┌────────────────┐
                                                  │  while true    │
       ┌───────────────────────────────────┐      │  do            │
       │ while true ; do echo \\007 ; done │ ::=  │    echo \\007  │
       └───────────────────────────────────┘      │  done          │
                                                  └────────────────┘
                                                    ┌─────────────────┐
                                                    │  for i in 1 2 3 │
       ┌──────────────────────────────────────┐     │  do             │
       │for i in 1 2 3 ; do echo \\007 ; done │ ::= │    echo \\007   │
       └──────────────────────────────────────┘     │  done           │
                                                    └─────────────────┘
    




     3.3.3.1 : shift  DECALAGE DES ARGUMENTS D'APPEL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                                           ┌────────────┐
       Décalage des arguments d'appel ::=  │ shift [n]  │
                                           └────────────┘
    

    La commande interne 'shift' permet de décaler les arguments d'appel de n positions ('n' est optionnel et est, par défaut, égal à 1).

          ┌─────────────────────────────────────────────────────┐
          │ $n+1 devient $1, $n+2 devient $2 et ainsi de suite. │
          └─────────────────────────────────────────────────────┘
                                              ┌───────────────────────┐
       Exemple pour des arguments d'appel  :  │ abc   def   ghi   jkl │
                                              └───────────────────────┘
          ┌─────────┐       ┌─────────────────┐
          │ echo $* │  ::=  │ abc def ghi jkl │
          └─────────┘       └─────────────────┘
          ┌─────────┐
          │ shift   │       ┌─────────────┐
          │ echo $* │  ::=  │ def ghi jkl │
          └─────────┘       └─────────────┘
          ┌─────────┐
          │ shift 3 │       ┌─────────────────┐
          │ echo $* │ ::=   │ une chaîne vide │
          └─────────┘       └─────────────────┘
    

    Si aucun argument d'appel n'existe, alors il y a un message d'erreur sur l'exécution du shift indiquant qu'il ne peut pas y avoir de décalage.

    Si l'on exécute plusieurs 'shift' consécutifs le dernier qui remet à zéro $1 s'exécute sans erreur, mais si l'on en exécute encore un, on se retrouve comme dans le premier cas (Pas d'argument d'appel) et dans ce cas il y a un message d'erreur.

    NOTE : $0 (nom de la commande telle qu'elle a été appelée) n'est pas concerné par 'shift'.

    Un script devant gérer des options et des arguments peut utiliser 'shift' pour analyser un par un les arguments d'options avant de traiter les vrais arguments, mais la commande 'getopts' permet une aide efficace pour l'analyse des arguments d'option (Voir 'getopts').




     3.3.3.2 : getopts ANALYSE DES OPTIONS D'UNE COMMANDE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
       ┌──────────────────────────────────────────────────────────────────────┐
       │ getopts ::=  Analyse des options d'appel d'un script en fonction de  │
       │                la présentation normalisée des options.               │
       └──────────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
       ┌─────────────────────────────────────────────────┐
       │ getopts liste_car_opt nom_var [ arg1 ... ]      │
       └─────────────────────────────────────────────────┘
    

    DESCRIPTION

    La commande interne 'getopts' permet d'analyser les arguments d'appel d'une commande et de récupérer les options sous forme de caractères isolés qu'il suffira de mémoriser au fur et à mesure.

    Il s'agit d'une nouvelle version de l'ancienne commande 'getopt' qui existait dans les anciennes versions de système. (Voir NOTES) La commande 'getopts' prend en charge les arguments d'appel (qui arrivent sous la forme $1, $2, etc.) et analyse ceux qui commencent par un '-' et qui peuvent, selon les normes des options, comporter un ou plusieurs caractères d'option regroupés.

    Un script SHELL utilisant de nombreuses options devrait, sans 'getopts', analyser des chaînes, différentes sur la forme, mais logiquement identiques comme dans l'exemple suivant.

    Les règles standard d'appel d'une fonction sont définies dans les règles 3-10 de 'intro(1)' (Voir le chapitre 'NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS').

    Imaginons une commande qui attend :

        ┌──────────────────────────────────────────────────────────────────┐
        │ - Une option '-a' ou '-b' .                                      │
        │     Si les deux sont spécifiées, seule la dernière spécifiée     │
        │     doit être prise en compte.                                   │
        │ - Une option '-o' suivie d'un nom de fichier destination.        │
        │ - Un ou plusieurs fichier(s) source(s) à traiter                 │
        └──────────────────────────────────────────────────────────────────┘
    

    Elle correspond à une présentation de syntaxe normalisée comme suit.

             ┌─────────────────────────────────────────────────────────┐
             │ usage : nom_cde [ -a | -b ] [ -o fic_dest ] fic_sce ... │
             └─────────────────────────────────────────────────────────┘
    

    L'utilisateur de cette commande doit pouvoir composer.

             ┌────────────────────────────────────────────┐
             │ nom_cde nom_fic_sce1 nom_fic_sce2          │
             │ nom_cde -a -o nom_fic_dest nom_fic_sce1    │
             │ nom_cde -bo nom_fic_dest -a                │
             │ nom_cde -o nom_fic_dest -a ── nom_fic_sce1 │
             │ nom_cde -o nom_fic_dest -b -a nom_fic_sce1 │
             └────────────────────────────────────────────┘
    

    Pour la saisie du nom de fichier destination la syntaxe '-onom_fic_dest' est historiquement équivalente à '-o nom_fic_dest' mais ne correspond pas aux normes standard. Pour l'instant 'getopts' la gère de façon équivalente mais ceci ne sera plus vrai dans les versions futures, voir le paragraphe 'NOTES'.

    Le script correspondant à la commande doit analyser $1, $2 etc... de façon à vérifier la bonne forme des options et trouver la séparation entre 'options' et autres arguments (l'argument '-- ' n'est pas obligatoire pour séparer les options des autres arguments). Cela devient vite un casse-tête car les options peuvent apparaître dans un ordre et sous des formes très variées (cet exemple avec trois options laisse envisager le nombre de combinaisons possibles avec un plus grand nombre d'options.

    Les options attendant un argument (Dans notre exemple l'option '-o nom_fic_dest') posent aussi un problème car il faut vérifier que, dès qu'une telle option est spécifiée, il y a bien une chaîne de caractères qui correspond à cet argument. (Voir 'NOTE' pour la saisie sous la forme '-onom_fic_dest'). La normalisation de présentation des options indique que si l'on doit spécifier plusieurs arguments, alors ceux-ci doivent être encadrés entre «"» ou «'» ou encore séparés par des "," de façon à se présenter sous la forme d'une seule chaîne de caractères.

    La commande 'getopts' va aider considérablement à l'analyse de ces différents problèmes.

    On fournit à 'getopts' :

     ┌───────────────┐
     │ liste_car_opt │ ::= La liste des caractères autorisés comme option
     └───────────────┘       en marquant avec un ':' les options qui doivent
    

    être suivies par un ou plusieurs arguments.

    Donc, dans notre cas, on spécifiera 'abo:'
     ┌─────────┐
     │ nom_var │       ::= Le nom de la variable dans laquelle 'getopts' devra
     └─────────┘             charger chaque caractère d'option qu'il aura
    

    rencontré.

    Le contenu de cette variable sera à la disposition du programmeur qui pourra le traiter par un 'case' ou une série de 'if' appropriés.

     ┌───────────┐
     │ arg1 .... │     ::= Liste des arguments que 'getopts' devra analyser au
     └───────────┘           lieu d'analyser les arguments standard $1, $2,
    

    etc....

    Donc si l'on spécifie un ou plusieurs arguments derrière le nom de variable ('nom_var') ce ou ces arguments seront analysés comme des arguments d'options tels qu'ils auraient été appelés sous SHELL interactif.

    Dans notre exemple, si l'on désire simuler la saisie des options '-a' et -o toto', il suffit d'appeler 'while getopts abo: opt -a -o toto .....'.

    'getopts' examinera les arguments d'appel et pour chaque caractère présenté comme une option ( sous la forme '-a' ou '-bo') il vérifiera que ce caractère figure dans la liste des caractères spécifiés dans 'liste_car_opt'. Dans le cas contraire il affiche de lui-même un message indiquant que ce caractère n'est pas un caractère autorisé comme option et retourne dans la variable un '?' que le programmeur pourra tester comme il l'entend (affichage de la syntaxe d'appel du script et sortie avec code de retour égal à deux).

    Le message d'erreur standard pour un caractère d'option non défini dans la liste des caractères d'options autorisés sera de la forme :

                 ┌─────────────────────────────────────────┐
                 │ nom_script : ERROR: Illegal option -- x │
                 └─────────────────────────────────────────┘
    

    Chaque fois que 'getopts' analyse une chaîne d'option (commençant par un '-' ou l'argument d'une option qui attend des arguments), il incrémente une variable d'environnement 'OPTIND' qui indique le nombre d'arguments qui ont été traités par 'getopts' comme des arguments d'option.

    Chaque fois qu'il rencontre un caractère d'option marqué avec un ':' (dans la liste des caractères autorisés en option) 'getopts' retourne dans une variable 'OPTARG' la chaîne de caractères qui suit.

    Si l'option concernée attend plusieurs arguments ceux-ci doivent être encadrés entre «"» ou «'» ou séparés par des ',', afin de se présenter sous la forme d'une seule chaîne pour le SHELL comme pour 'getopts'. De toute façon 'getopts' retourne la chaîne reçue sans la traiter.

    Si une telle option n'est pas suivie d'un argument (Exemple : appel du script avec '-a -o' au lieu de '-a -o nom_fich'), alors 'getopts' affiche un message de la forme suivante et retourne un '?' dans la variable réceptrice.

                ┌─────────────────────────────────────────────────────┐
                │ nom_script: ERROR: Option requires an argument -- o │
                └─────────────────────────────────────────────────────┘
    

    Il est à noter que si l'on appelle le script avec '-o -a', alors 'getopts' considère que '-a' est l'argument spécifié pour l'option '-o' et ceci est bien conforme à la norme de présentation des options.

           ┌──────────────────┐      '-a' est alors considéré comme argument
           │ nom_script -o -a │ ::=  de l'option '-o' et non pas une option.
           └──────────────────┘      à part entière.
    

    Lorsque 'getopts' a atteint la fin des options (plus d'argument commençant par '-' ou argument '--' rencontré), 'getopts' retourne un code de retour différent de zéro. Donc on pourra utiliser une boucle 'while getopts liste_car_opt nom_var' pour traiter les caractères envoyés par 'getopts', et en fin de boucle il suffit d'utiliser un 'shift' avec '$OPTIND -1' pour récupérer les vrais arguments d'appel du script.

    Pour écrire un script utilisant 'getopts' il suffira :

    - De faire une boucle 'while getopts .....', - De traiter dans cette boucle chaque caractère d'option isolé par 'getopts' afin de les stocker dans les variables appropriées.

    - Pour les options attendant un ou plusieurs arguments de récupérer ceux-ci, à partir de '$OPTARG', dans les variables appropriées.

    - En fin de boucle utiliser 'OPTIND' pour faire un décalage des arguments d'options (traités par 'getopts' et donc devenus inutiles) et de traiter les arguments réels dans le déroulement normal du script.

    NOTES

    Pour des options nécessitant la saisie d'argument (dans notre exemple il s'agit de l'option '-o nom_fic_dest'), historiquement, l'on pouvait composer cet argument sous deux formes :

               ┌─────────────────┐       ┌────────────────┐
               │ -o nom_fic_dest │   ou  │ -onom_fic_dest │
               └─────────────────┘       └────────────────┘
    

    Seule la première présentation correspond aux normes standard de spécification des options. Pour l'instant 'getopts' supporte les deux syntaxes, mais ceci ne sera plus vrai dans les futures versions de système.

    Comme 'getopts' utilise 'OPTIND' pour gérer sa progression dans les arguments spécifiant des options, il est fortement déconseillé de modifier sa valeur. Au début d'une session SHELL cette variable est initialisée à 1 et l'on peut utiliser son contenu, mais pas le modifier sous peine d'obtenir un fonctionnement imprévisible de 'getopts'.

    La commande 'getopts' est une amélioration de l'ancienne commande 'getopt' qui était utilisable sur les anciennes versions. Pour des raisons de compatibilité, cette ancienne commande subsiste sur les versions actuelles mais ceci ne sera plus vrai dans les versions futures.

    Les anciens scripts utilisant 'getopt' peuvent être convertis en utilisant '/usr/lib/getoptcvt -b anc_nom_script >nouv_nom_script' Si l'ancien script ne contient pas d'appels corrects de 'getopt', il n'y a pas de conversion, affichage d'un '?' et sortie avec un code de retour différent de 0.

    EXEMPLES

       ┌─────────────────────  Script appelé 'essai' ─────────────────────────┐
       │ USAGE="usage: $0 [ -a | -b ] [ -o fic_dest ] fic_sce ... "           │
       │ ####### DEBUT ANALYSE DES OPTIONS ################################## │
       │ while getopts abo: opt                                               │
       │ do                                                                   │
       │   case "$opt" in                                                     │
       │      a | b  )    FLAG="$opt";;                                       │
       │      o      )    NOM_FIC_DEST="$OPTARG";;                            │
       │      \?     )    echo $USAGE                                         │
       │                  exit 2;;                                            │
       │   esac                                                               │
       │ done                                                                 │
       │ shift `expr "$OPTIND" - 1`                                           │
       │ ####### FIN ANALYSE DES OPTIONS #################################### │
       │ ####### DEBUT DE SCRIPT ############################################ │
       │ echo 'FLAG = ' $FLAG                                                 │
       │ echo 'DEST = ' $NOM_FIC_DEST                                         │
       │ for i in $*                                                          │
       │ do                                                                   │
       │  echo 'SCE  = ' $i                                                   │
       │ done                                                                 │
       └──────────────────────────────────────────────────────────────────────┘
    

      ┌  essai -a toto titi ─┐ ┌ essai -a -o toto titi ┐ ┌ essai -b -o -a titi ┐
      │  FLAG =  a           │ │ FLAG =  a             │ │ FLAG =  b           │
      │  DEST =              │ │ DEST =  toto          │ │ DEST =  -a          │
      │  SCE  =  toto        │ │ SCE  =  titi          │ │ SCE  =  titi        │
      │  SCE  =  titi        │ └───────────────────────┘ └─────────────────────┘
      └──────────────────────┘  Option '-a' et '-o'       Option '-b' et fichier
    

    Une seule option '-a' '-a' en destination.

      ┌ essai -b -o toto -- titi ┐             ┌ essai -a -b -ototo titi ┐
      │ FLAG =  b                │             │ FLAG =  b               │
      │ DEST =  toto             │             │ DEST =  toto            │
      │ SCE  =  titi             │             │ SCE  =  titi            │
      └──────────────────────────┘             └─────────────────────────┘
    

    Séparation 'opt/arg' par '--' Syntaxe encore tolérée

          ┌ essai -y -o toto titi ───────────────────────────────┐
          │ essai: ERROR: Illegal option -- y                    │
          │ usage: essai [ -a | -b ] [ -o fic_dest ] fic_sce ... │
          └──────────────────────────────────────────────────────┘
    

    Option 'y' non acceptée

          ┌ essai -a -o ─────────────────────────────────────────┐
          │ essai: ERROR: Option requires an argument -- o       │
          │ usage: essai [ -a | -b ] [ -o fic_dest ] fic_sce ... │
          └──────────────────────────────────────────────────────┘
    

    Option '-o' utilisée sans argument

    Si on désire, dans un script, faire de la simulation d'options on pourra, toujours avec le même exemple de base, utiliser :

       ┌───────────────────────────────────┐
       │ while getopts abo: opt -a -o toto │
       └───────────────────────────────────┘
    

    Cette forme d'appel de 'getopts' fait que l'on analyse le ou les arguments spécifiés en lieu et place des arguments d'appel réels du script.

    Dans ce cas il n'est plus utile de faire un décalage des arguments d'appel puisque ceux-ci n'ont pas été traités par 'getopts'. On peut donc supprimer la ligne 'shift `expr "$OPTIND" - 1`' et faire de la simulation avec les arguments spécifiés dans le script.




     3.3.3.3 : exit  SORTIE AVEC/SANS CODE RETOUR   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌───────────────────────────────────────────────────────┐
        │ exit ::=  Sortie script/processus avec code de retour │
        └───────────────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌──────────────────────┐
        │ exit [ code_retour ] │
        └──────────────────────┘
    

    DESCRIPTION La commande interne 'exit' permet de sortir du processus ou du script en cours avec positionnement du code de retour spécifié.

    Si l'on était sous le prompt du SHELL on termine la session de SHELL avec retour au login, si celle-ci était le processus de base. Ceci est donc équivalent à 'CTRL+D'.

    Dans un script (interprété par le SHELL dans un processus) on arrête l'interprétation et l'on quitte le processus.

          ┌───────────────────┐
          │ exit              │
          │ exit 0            │
          │ exit 1            │
          │ exit $CODE_RETOUR │
          └───────────────────┘
    

    Les codes de retour utilisables sous SHELL sont des entiers positifs compris entre 0 et 255.

    Par convention :

          ┌───┐
          │ 0 │     ::= Commande exécutée normalement.
          └───┘
     ┌───────────┐
     │ Valeur >0 │  ::= Commande non exécutée correctement.
     └───────────┘
    

    Le code de retour peut être évalué avec la variable d'environnement '$?'.




     3.3.3.4 : read  SAISIE D'INFORMATION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌────────────────────────────────────────────────────────────────┐
        │ read ::= Lecture fichier entrée standard dans une ou plusieurs │
        │            variables.                                          │
        └────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌──────────────────────┐
        │ read nom_var1 ...    │
        └──────────────────────┘
    

    DESCRIPTION La commande interne 'read' permet de lire des caractères sur le fichier standard d'entrée dans une ou plusieurs variables d'environnement.

    A partir du clavier les caractères sont envoyés dès la validation par la touche retour.

    A partir d'un fichier les caractères sont lus jusqu'au caractère de fin de ligne.

    Mais dans les deux cas le caractère de validation ou de fin de ligne n'est pas envoyé dans la variable.

    S'il n'y a qu'une variable d'environnement spécifiée pour le 'read', alors la totalité des caractères est envoyée dans cette variable.

    Dans le cas contraire, il y a comme pour un passage d'arguments, interprétation des espaces ou des tabulations comme séparateur et chaque mot sera envoyé dans la variable correspondante.

    Si le nombre de variables est insuffisant pour le nombre de mots alors la dernière variable reçoit l'ensemble des mots restants.

    Si le nombre de variables est plus important, les variables inutilisées sont remises à zéro sous forme de chaînes vides.

    CODES RETOUR
       ┌───────────────────────────────────────────────────────────────┐
       │ 0 ::= Lecture effectuée normalement                           │
       │ 1 ::= Lecture vide (CTRL+D ou EOF) sans aucun autre caractère │
       └───────────────────────────────────────────────────────────────┘
    




     3.3.3.5 : trap  MASQUAGE DE SIGNAUX   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                    ┌───────────────────────────────────┐
       trap    ::=  │ trap                              │
                    │ trap [liste_commandes] no_signal  │
                    └───────────────────────────────────┘
    

    La commande interne 'trap' permet une gestion des signaux d'interruption et permet d'indiquer en argument la ou les commandes à exécuter lorsque le signal d'interruption spécifié se produit.

    La commande 'trap' sans liste de commande ni numéro de signal permet de visualiser le ou les 'trap' déjà positionnés ainsi que leurs commandes associées.

    Le contenu de 'liste_commandes' sera évalué uniquement lorsqu'un 'trap' a été spécifié et lorsque le signal spécifié pour ce 'trap' se produit.

    Les commandes 'trap' sont exécutées dans l'ordre des numéros de signal ou leur correspondant symbolique.

    Sans liste de commande pour un numéro de signal, alors le 'trap' pour le signal spécifié revient à son état initial.

    Si n est égal à zéro, alors la commande 'arg' est exécutée en fin d'exécution du SHELL. (Signal 0 ::= Fin de SHELL)

    Liste des signaux :

     ┌────────────────────────────────────────────────────────────────────┐
     │  0 EXIT     ::= Fin d'exécution normale du SHELL                   │
     │  1 SIGUP    ::= Hangup  (Ligne du tty interrompue, coupure ligne)  │
     │  2 SIGINT   ::= Interrupt  'CTRL+C'                                │
     │  3 SIGQUIT  ::= Abandon (Quit)                                     │
     │  4 SIGILL   ::= Instruction illégale                               │
     │  5 SIGTRAP  ::= Trace trap                                         │
     │  6 SIGABRT  ::= Abort (par la procédure 'abort')                   │
     │  7 SIGEMT   ::= Emulation trap                                     │
     │  8 SIGFPE   ::= Erreur op.arithmétique                             │
     │  9 SIGKILL  ::= Kill                                               │
     │ 10 SIGBUS   ::= Erreur bus                                         │
     │ 11 SIGSEGV  ::= Segmentation violation (Erreur d'adresse mémoire)  │
     │ 12 SIGSYS   ::= Mauvais argument lors d'un appel système           │
     │ 13 SIGPIPE  ::= Ecriture dans un 'pipe' ou 'socket' jamais lu      │
     │ 14 SIGALRM  ::= Alarme d'horloge                                   │
     │ 15 SIGTERM  ::= Signal d'arrêt software                            │
     └────────────────────────────────────────────────────────────────────┘
    

    Exemple :

          ┌─────────────┐
          │ trap exit 2 │      ::=  Sortie si l'on compose 'CTRL+C'
          └─────────────┘
    

          ┌──────────────────┐
          │ trap "exit 15" 2 │ ::= Sortie avec code retour 15 si l'on compose
          └──────────────────┘       'CTRL+C'.
    

          ┌──────────────────────────────────────┐
          │ trap "rm -f /tmp/travail ; exit 1" 2 │::= Sortie avec destruction
          └──────────────────────────────────────┘    du fichier '/tmp/travail'
    

    et code de retour 1 si l'on compose 'CTRL+C'.

          ┌───────────┐
          │ trap "" 2 │        ::=  Désactivation du 'CTRL+C'
          └───────────┘
    




     3.3.3.6 : exec  EXECUTION COMMANDE/PROCESSUS COURANT   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                    ┌─────────────────────────────────────────────────┐
       exec    ::=  │ exec cde [options] [arguments] [redirections]   │  'Fmt 1'
                    │ exec redirections                               │  'Fmt 2'
                    └─────────────────────────────────────────────────┘
    

    FORMAT 1 La commande 'exec' permet de spécifier une ou plusieurs commandes qui devront s'exécuter dans le même processus au lieu de le faire comme c'est l'habitude dans un processus fils. Il s'agit en fait d'une demande de substitution du SHELL courant par la commande spécifiée. Si cette demande est faite dans le SHELL du 'login', en fin d'exécution de commande le processus en cours est détruit et le poste est déconnecté.

    Exemple d'appel d'un exécutable qui travaillera avec le même environnement que le script lui-même en se substituant à lui :

          ┌───────────────────────────────────────┐
          │ exec tmenu fmx.basic home x           │
          └───────────────────────────────────────┘
    

    FORMAT 2 En absence de commande à exécuter mais avec seulement des redirections un 'exec' permet de faire une redirection des fichiers standard en cours d'exécution.

    Exemple :

         ┌──────────────┐
         │  echo 1      │
         │  echo 2      │
         │  echo 3      │
         │  exec >titi  │
         │  echo 4      │
         │  echo 5      │
         │  echo 6      │
         └──────────────┘
    

    Dans cet exemple, les nombres 1, 2 et 3 seront affichés sur la sortie standard, mais à partir de 4 les affichages seront redirigés vers le fichier "titi".




     3.3.3.7 : if,then,else,elif,fi INSTRUCTION CONDITIONNELLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                                      ┌────────────────────┐
       Instruction Conditionnelle ::= │ if commande1       │
                                      │   then commande2   │
                                      │ fi                 │
                                      └────────────────────┘
    

                                      ┌────────────────────┐
                                      │ if commande1       │
                                      │   then commande2   │
                                      │   else commande3   │
                                      │ fi                 │
                                      └────────────────────┘
          ┌────────────────────────┐        ┌──────────────────────┐
          │ if commande1           │        │ if commande1         │
          │   then commande2       │        │   then commande2     │
          │   else if commande3    │        │   elif commande3     │
          │        then commande4  │        │     then commande4   │
          │        else commande5  │        │     else commande5   │
          │        fi              │        │ fi                   │
          │ fi                     │        └──────────────────────┘
          └────────────────────────┘
    

    Contrairement à des langages classiques (COBOL, BASIC) le SHELL interprète derrière un 'if' le code de retour d'une commande et non pas la valeur d'une expression conditionnelle. La commande 'if' combinée avec la commande 'test' permettra de réaliser des tests classiques (Voir la commande 'test'). Mais la structure 'if commande then ...' permet une utilisation beaucoup plus puissante qu'un simple 'if condition ....'.

    L'instruction 'if' exécute la commande spécifiée et teste le code de retour de cette commande pour exécuter :

    - les commandes spécifiées par 'then' si ce code est égal à zéro - les commandes spécifiées par 'else' si ce code est différent de zéro.

    La partie 'else' est optionnelle et ne doit être spécifiée que si l'on désire spécifier des commandes à exécuter en cas de code retour différent de zéro.

    ATTENTION : Pour le langage 'C' un 'if' évalue l'expression conditionnelle de façon inverse puisque les instructions qui suivent le 'if' (en 'C' il n'y a pas de 'then') sont exécutées si l'expression a une valeur différente de 0 et celles qui suivent le 'else' si l'expression a une valeur égale à zéro.

    En fait si l'on utilise derrière le 'if' une commande 'test' (ou [expr.cond] ou [[expr.cond]] ), ces commandes renvoient '0' pour 'vrai' et une valeur différente de zéro pour 'faux'.

    Dans ce cas c'est la logique interne (vrai,faux) qui est inversée par rapport au 'C', mais la logique de programmation reste standard.

    Pour
            ┌────────────────┐    ┌───────────────────────────┐    ┌───────────────────────────┐    ┌────────────────────────────┐
            │ if condition   │    │ if test chaîne1 = chaîne2 │    │ if [ chaîne = chaîne2 ]   │    │ if [[ chaîne1 = chaîne2 ]] │
            │ then commande1 │    │ then commande1            │    │ then commande1            │    │ then commande1             │
            │ else commande2 │    │ else commande2            │    │ else commande2            │    │ else commande2             │
            │ fi             │    │ fi                        │    │ fi                        │    │ fi                         │
            └────────────────┘    └───────────────────────────┘    └───────────────────────────┘    └────────────────────────────┘
    

         Si condition retourne 0    Si le test est OK alors
         on exécute 'commande1'.    'test' retourne 0 et on
         Sinon on exécute            exécute 'commande1'.
         'commande2'                Sinon 'test' retourne une
                                     valeur différente de '0'
                                     et on exécute 'commande2'.
    

    Exemples d'utilisation de 'if ... then .... else .... fi'
        ┌────────────────────┐
        │ if condition       │  Utilisation de l'instruction vide ':' pour ne rien exécuter si la condition est réalisée
        │   then :           │  et exécuter une ou plusieurs instructions dans le cas contraire. 
        │   else instruction │  On pourrait aussi inverser la condition et ne plus se servir de 'else'.
        │ fi                 │  
        └────────────────────┘  
    

    Les séparateurs de commandes '&&' ou '||' peuvent remplacer une condition du genre 'if condition then ... fi' ou 'if condition then : else .... fi' du moment que l'on ne définit qu'une action et une seule (et non pas une alternative entre deux actions en fonction du résultat du test).

           ┌──────────────────────┐
           │ if [ -s nom_fic ]    │      ┌───────────────────────────────┐
           │    then cat nom_fic  │  ::= │ [ -s nom_fic ] && cat nom_fic │
           │ fi                   │      └───────────────────────────────┘
           └──────────────────────┘
       ┌───────────────────────────┐
       │ if [ -s nom_fic ]         │     ┌─────────────────────────────────────┐
       │    then :                 │ ::= │ [ -s nom_fic ] || echo " " >nom_fic │
       │    else echo " " >nom_fic │     └─────────────────────────────────────┘
       │ fi                        │
       └───────────────────────────┘
    




     3.3.3.8 : case . in . esac  EXECUTION CONDITIONNELLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                                      ┌────────────────────────────┐
        Exécution conditionnelle  ::= │ case texte_à_tester in     │
                                      │    cible_1 ) commande1 ;;  │
                                      │    cible_2 ) commande2 ;;  │
                                      │    ......................  │
                                      │ esac                       │
                                      └────────────────────────────┘
                           ┌───────────────────────────────────────────────────┐
        texte_à_tester ::= │Texte ou variable d'environnement dont on évaluera │
                           │le contenu                                         │
                           └───────────────────────────────────────────────────┘
    

                           ┌────────────────────────┐
        cible_n        ::= │Valeur [ | valeur ... ] │
                           └────────────────────────┘
    

    valeur ::= Texte (contenant éventuellement des méta-caractères) dont la comparaison avec le 'texte_à_tester' déclenchera la ou les commandes qui sont derrière le ')'.

    A noter le double ';' en fin de la liste des commandes.

    Méta-caractères :

    * ::= Chaîne quelconque de zéro ou plus caractères quelconques y compris le '.' et le '/'.

    ? ::= Un caractère quelconque y compris le '.' et le '/'.

    [xyz] ::= Tout caractère dans la liste des spécifiés [a-z] ::= Tout caractère compris entre ceux spécifiés [^xyz] ::= Tout caractère autre que ceux spécifiés.

    [^a-z] ::= Tout caractère non compris entre ceux spécifiés
                     ┌──────────────────────────────────────┐
        Exemple   :  │  case $1 in                          │
                     │     -x*   ) echo Option x ;;         │
                     │     -a|-A ) echo Option -a ou -A ;;  │
                     │     -*    ) echo Option inconnue ;;  │
                     │     *     ) echo Pas -option ;;      │
                     │  esac                                │
                     └──────────────────────────────────────┘
    

    Cet exemple simpliste ne permet pas de gérer les options présentées de façon complexe comme 'nom_script -xyz' ::= 'nom_script -x -y -z'.

    La commande 'getopts' permet une analyse de toutes les formes autorisées de présentation des options. (Voir 'getopts')




     3.3.3.9 : test -x ...  TEST FICHIER OU CHAINES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

     ┌──────────────────┐
     │ test expression  │
     │ [ expression ]   │
     └──────────────────┘
    

    La fonction 'test' évalue l'expression spécifiée et si la valeur de cette expression est 'vraie' retourne un code 0. Dans le cas contraire le retour est différent de zéro.

    NOTE : Les valeurs de retour sont donc inversées par rapport au 'C' puisque le retour de 'vrai' est '0' alors que le retour de 'faux' est différent de zéro (Voir fonctions 'true' et 'false').

    Ce genre de fonction est couramment utilisé avec des 'if ...' mais peut aussi être utilisé pour générer un code de retour.

    Il existe trois formes d'écriture :

            ┌─────────────────┐        ┌────────────────┐             ┌──────────────────┐
            │ test expression │   ou   │ [ expression ] │  ou encore  │ [[ expression ]] │
            └─────────────────┘        └────────────────┘             └──────────────────┘
    

    La commande [[ expression ]] est décrite dans le chapitre suivant.

    Dans le cas où l'on utilise des "[]" il doit y avoir obligatoirement au moins un espace entre le '[' et le début de l'expression et entre la fin de l'expression et le ']'.

    Exemple :

      ┌────────────────────┐             ┌─────────────────────┐
      │ if test -r fichier │             │ if [ -r fichier ]   │
      │ then               │    ::=      │ then                │
      │  ....              │             │   ...               │
      │ fi                 │             │ fi                  │
      └────────────────────┘             └─────────────────────┘
    

    Les expressions conditionnelles peuvent être définies avec des primitives afin de préciser le genre de test désiré. Dans le cas d'utilisation de primitive il doit y avoir au moins un espace entre la primitive et l'argument de cette primitive.

    ATTENTION : Pour des opérandes utilisant des variables d'environnement, celles-ci devront être encadrées par des «"» surtout si elles peuvent être vides. Exemple [ $nom = $i ] ne sera pas syntaxiquement correct si '$i' ou '$nom' est vide (car il manquerait un opérande) , alors que [ "$nom" = "$i" ] sera toujours correct.

       -z chaîne1         ::=  Vraie si la taille de la chaîne est zéro.
       -n chaîne1         ::=  Vraie si la taille de la chaîne est différente de zéro
       chaîne1            ::=  Vraie si la chaîne spécifiée n'est pas vide.
       chaîne1 = chaîne2  ::=  Vraie si les chaînes spécifiées sont identiques.
       chaîne1 != chaîne2 ::=  Vraie si les chaînes spécifiées sont différentes.
    
       opérateurs sur des entiers 
        ent1 -eq ent2      ::=  Vraie si les entiers spécifiés sont identiques.
        ent1 -ne ent2      ::=  Vraie si les entiers spécifiés sont différents.
        ent1 -gt ent2      ::=  Vraie si ent1 >  ent2.
        ent1 -ge ent2      ::=  Vraie si ent1 >= ent2.
        ent1 -lt ent2      ::=  Vraie si ent1 <  ent2.
        ent1 -le ent2      ::=  Vraie si ent1 <= ent2.
    
         opérateurs sur des noms de fichier 
        -r nom_fichier      ::=  Vraie si le fichier existe et accessible en lecture.
        -w nom_fichier      ::=  Vraie si le fichier existe et accessible en écriture.
        -x nom_fichier      ::=  Vraie si le fichier existe et accessible en exécution.
        -s nom_fichier      ::=  Vraie si le fichier existe et s'il a une taille différente de zéro.
        -f nom_fichier      ::=  Vraie si le fichier existe et s'il s'agit d'un fichier régulier (fichier de données ou exécutable mais pas un répertoire ni
                                             un fichier spécial avec 'major/minor', etc...).
        -d nom_fichier      ::=  Vraie si le fichier existe et est un répertoire.
        -t [no_fichier]     ::=  Vraie si le fichier standard spécifié par -t son numéro est un 'tty' ou non.
                                           -t 0   Ce test permet donc de savoir s'il y a
                                           -t 1   ou non redirection du fichier standard
                                           -t 2   spécifié ('0=Input, 1=Output, 2=Erreur').
                                                  Les "[]" ne représentent ici que le caractère optionnel du numéro de fichier standard
                                                  car par défaut la valeur 1 est prise de façon à tester si la sortie standard est
                                                  un 'tty' ou non. Ils ne sont pas syntaxiques.
        -c nom_fichier      ::=  Vraie si le fichier existe et est un fichier spécial de type caractère (Ex.: 'crw-rw-rw-').
        -b nom_fichier      ::=  Vraie si le fichier existe et est un fichier spécial de type bloc (Ex.: 'brw-rw-rw-').
        -p nom_fichier      ::=  Vraie si le fichier existe et est un 'pipe' nommé (fichier 'FIFO') (Ex.: 'prw-rw----').
        -u nom_fichier      ::=  Vraie si le fichier existe et si son 'set-user-id' est positionné.
        -g nom_fichier      ::=  Vraie si le fichier existe et si son 'set-group-id' est positionné.
        -k nom_fichier      ::=  Vraie si le fichier existe et si son 'sticky-bit' est positionné.
    
    

    De plus ces primitives pourront être combinées avec :

           ┌───────────────────────────────────┐
           │   !   ::=  Opération de négation  │
           │                                   │
           │   -a  ::=  'Et' logique binaire   │
           │                                   │
           │   -o  ::=  'Ou' logique binaire   │
           └───────────────────────────────────┘
    

    et des "()" pour grouper si nécessaire des primitives entre elles mais dans ce cas, se souvenir que les parenthèses sont des caractères spéciaux du SHELL et qu'il faut donc les marquer avec un '\'.

    EXEMPLES :

          ┌─────────────────────────────────┐
          │ test -d $nom_rep -a -w $nom_rep │ ::= Test d'un répertoire dans
          └─────────────────────────────────┘     lequel on peut écrire.
    

    Exemples d'utilisation avec 'if ... then .... fi' :

       ┌──────────────────────────────────────────────────────────────────────────────┐
       │ if [ $nomfic = $destination ] ; then .........  ::= Egalité entre chaînes    │
       │ if [ $# -lt 2 ] ; then .....                    ::= Nombre arg. <2           │
       │ if [ -s $nomfic ] ; then .....                  ::= Fichier existant et      │
       └──────────────────────────────────────────────────────────────────────────────┘
    




     3.3.3.10 : [[ expression_conditionnelle ]]  TEST FICHIER 
        OU CHAINES
      Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La commande [[ expression_conditionnelle ]] remplace les commandes 'test xxxx' ou '[ xxxxx ]'.

    Elle introduit un nouvel opérateur =~

    Ce genre de fonction est couramment utilisé avec des 'if ...' mais peut aussi être utilisé directement pour générer un code de retour.

    La différence joue principalement sur l'interpolation du contenu entre les [[ et ]].

    Prenons un exemple avec a=A et b='' (La variable a contient un caractère mais la variable b est vide) :

          Avec [ $a = $b ]   l'interpolation des variables se fait avant l'interprétation du test et donc [ A = ] sera invalide.
                             ceci obligeait à des encadrements obligatoires du genre [ "$a" = "$b" ]
          Avec [[ $a = $b ]] l'interpolation se fera après vérification de la syntaxe du test. Donc un variable vide n'entrainera
                             pas une erreur de synatxe comme précédemment.
    

         ┌──────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
         │ -a fichier       │  Vrai si le fichier existe.                                                                                                          │                                                                         
         │ -b fichier       │  Vrai si le fichier existe et est un fichier spécial bloc.                                                                           │                                                                                                        
         │ -c fichier       │  Vrai si le fichier existe et est un fichier spécial caractère.                                                                      │                                                                                                             
         │ -d fichier       │  Vrai si le fichier existe et est un répertoire                                                                                      │                                                                                             
         │ -e fichier       │  Vrai si le fichier existe.                                                                                                          │                                                                         
         │ -f fichier       │  Vrai si le fichier existe et est un fichier régulier.                                                                               │                                                                                                    
         │ -g fichier       │  Vrai si le fichier existe et a son bit Set-GID positionné.                                                                          │                                                                                                         
         │ -h fichier       │  Vrai si le fichier existe et est un lien symbolique.                                                                                │                                                                                                   
         │ -k fichier       │  Vrai si le fichier existe et a son bit « sticky » positionné.                                                                       │                                                                                                            
         │ -p fichier       │  Vrai si le fichier existe et est un tube nommé (FIFO).                                                                              │                                                                                                     
         │ -r fichier       │  Vrai si le fichier existe et est accessible en lecture.                                                                             │                                                                                                      
         │ -s fichier       │  Vrai si le fichier existe et a une taille non nulle.                                                                                │                                                                                                   
         │ -t fd            │  Vrai si fd est ouvert sur un terminal.                                                                                              │                                                                                     
         │ -u fichier       │  Vrai si le fichier existe et a son bit Set-UID positionné.                                                                          │                                                                                                         
         │ -w fichier       │  Vrai si le fichier existe et est accessible en écriture.                                                                            │                                                                                                       
         │ -x fichier       │  Vrai si le fichier existe et est exécutable.                                                                                        │                                                                                           
         │ -O fichier       │  Vrai si le fichier existe et appartient à l'ID effectif de l'utilisateur.                                                           │                                                                                                                        
         │ -G fichier       │  Vrai si le fichier existe et appartient au groupe effectif de l'utilisateur.                                                        │                                                                                                                           
         │ -L fichier       │  Vrai si le fichier existe et est un lien symbolique.                                                                                │                                                                                                   
         │ -S fichier       │  Vrai si le fichier existe et est une socket                                                                                         │                                                                                          
         │ -N fichier       │  Vrai si le fichier existe et a été modifié depuis sa dernière lecture.                                                              │                                                                                                                     
         │ fic_1 -nt fic_2  │  Vrai si le fic_1 est plus récent que le fic_2, d'après les dates de modification, ou si fic_1 existe et pas fic_2.                  │                                                                                                                                                                 
         │ fic_1 -ot fic_2  │  Vrai si le fic_1 est plus vieux que le fic_2 ou si fic_2 existe et pas fic_1.                                                       │                                                                                                                            
         │ fic_1 -ef fic_2  │  Vrai si le fic_1 et le fic_2 se réfèrent au même périphérique et ont les mêmes numéros d'i-node.                                    │                                                                                                                                                 
         ├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤                           
         │ -o nom_opt       │  Vrai si l'option shell nom_opt est active.                                                                                          │                                                                                         
         │                  │  Consulter la liste des options dans la description de l'argument -o de la commande interne 'set' plus bas.                          │                                                                                                                                                         
         ├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤                           
         │ -z chaîne        │  Vrai si la longueur de la chaîne est nulle.                                                                                         │                                                                                          
         ├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤                           
         │ chaîne           │  Vrai si la longueur de la chaîne est non-nulle.                                                                                     │                                                                                             
         │ -n chaîne        │                                                                                                                                      │                                                                                                  
         ├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤                           
         │ cha_1 == cha_2   │  Vrai si les deux chaînes sont égales. Le symbole = peut servir à remplacer == pour une stricte comformité POSIX.                    │                                                                                                                                                               
         │ cha_1 != cha_2   │  Vrai si les deux chaînes sont différentes.                                                                                          │                                                                                         
         │ cha_1 <  cha_2   │  Vrai si cha_1 se trouve avant cha_2 dans l'ordre lexicographique de la variable LOCALE en cours.                                    │                                                                                                                                               
         │ cha_1  > cha_2   │  Vrai si cha_1 se trouve après cha_2 dans l'ordre lexicographique de la variable LOCALE en cours.                                    │                                                                                                                                               
         │ cha_1 =~ cha_2   │  Vrai si cha_1 correspond à l'expression régulière spécifiée par cha_2                                                               │                                                                                                                                               
         ├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤                           
         │ arg1 -eq arg2    │                                                                                                                                      │                                        
         │ arg1 -ne arg2    │  Les opérateurs suivant -eq, -ne, -lt, -le, -gt, ou -ge renvoient la valeur vraie si arg_1 est respectivement égal, différent,       │                                                                                                                                                                            
         │ arg1 -lt arg2    │    inférieur, inférieur ou égal, supérieur, supérieur ou égal à arg2.                                                                │                                                                                                                                                                                       
         │ arg1 -le arg2    │                                                                                                                                      │                                             
         │ arg1 -gt arg2    │  Arg1 et arg2 peuvent être des entiers positifs ou négatifs.                                                                         │                                                                                                          
         │ arg1 -ge arg2    │                                                                                                                                      │                                        
         └──────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
    

         ┌─────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐
         │ [[ abcdefg =~ '^a' ]]                   │ Vrai                                                               │
         │ [[ abcdefg =~ ^a ]]                     │ Vrai                                                               │
         │ [[ abcdefg=~^a ]]                       │ Toujours vrai on teste 'abcdefg=~^a' en tant que chaîne non vide   │
         │ [[ abcdefg =~ ^[aA]                     │ Vrai                                                               │
         │ [[ abcdefg =~ ^[aA                      │ Erreur 1 (syntaxe incorrecte                                       │
         │ [[ abcdefg =~ ^a.*g$ ]]                 │ Vrai                                                               │
         │ [[ abcdefg =~ ^a.*z$ ]]                 │ Faux                                                               │
         │ [[ abcdefg =~ '^a(b' ]]                 │ Erreur 2 (syntaxte incorrecte)                                     │
         │ [[ abcdefg =~ '^a(b.*)' ]]              │ Vrai et {BASH_REMATCH[1]} contient bcdefg                          │
         │ [[ abcdefg =~ ^a(b.*)(e.*)$ ]]          │ Vrai et {BASH_REMATCH[1]} contient bcd                             │
         │                                         │         {BASH_REMATCH[2]} contient efg                             │
         └─────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘
    




     3.3.3.11 : for ... in ... do ... done  BOUCLE 'FOR'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                          ┌──────────────────────────────┐
       Boucle for     ::  │ for nom_var [ in liste_var ] │
                          │ do                           │
                          │  commande_1                  │
                          │  commande_2                  │
                          │  ......                      │
                          │ done                         │
                          └──────────────────────────────┘
    

    La boucle 'for' permet de traiter une liste d'arguments en donnant la valeur de chaque argument à la variable et en exécutant les instructions spécifiées entre 'do' et 'done' pour chaque valeur et ceci jusqu'à épuisement de la liste.

    Il ne s'agit pas d'un 'FOR ... NEXT' de style BASIC mais d'une boucle permettant de traiter une liste d'arguments.

    Exemple de boucle 'for' affichant ligne par ligne les arguments d'appel :

       ┌─────────────┐
       │ for i in $* │    Cet exemple très simple sera repris avec les
       │ do          │    boucles 'while' et 'until'.
       │  echo $i    │
       │ done        │
       └─────────────┘
    

    La partie 'in liste_var' est optionnelle est si elle est omise, par défaut le SHELL interprète 'in $*'.

    Il est à noter qu'une boucle 'for' ne ressemble pas aux boucles 'for' du BASIC ou du 'C'. Néanmoins il reste possible de faire des itérations avec 'for i in 1 2 3 4 5', 'for i in 1 3 5 7 9' et ainsi de suite.

    Pour boucler 10 fois sans avoir besoin d'un compteur il est aussi possible d'utiliser 'for i in x x x x x x x x x x'.

    Si une boucle doit être plus importante il reste la possibilité d'utiliser la boucle 'while'.

    Ne pas oublier les accolades qui permettent de préparer une liste d'arguments numériques ou alphabétiques croissants.

          ┌──────── Exemple de boucle de 0 à 255  ────────────────┐   ┌─ Boucle 0=>255 ────┐       ┌─ Boucle a=>z   ────┐ 
          │ i=0                         # Initialisation compteur │   │ for i in {0..255}  │       │ for i in {a..z}    │
          │ while [ $i -le 255 ]        # Boucle de 0 à 255       │   │ do                 │       │ do                 │
          │ do                                                    │   │   echo $i          │       │   echo $i          │
          │  echo $i " \c"                                        │   │ done               │       │ done               │
          │  i=`expr $i + 1`            # Incrémentation compteur │   └────────────────────┘       └────────────────────┘
          │ done                                                  │
          └───────────────────────────────────────────────────────┘
    

    Voir 'while' , 'test' ( [ xx -le yy ] ) et 'expr'.




     3.3.3.12 : while ... do ... done  BOUCLE 'WHILE'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                          ┌──────────────────────────────┐
       Boucle while   ::  │ while commande_test_boucle   │
                          │ do                           │
                          │  commande_1                  │
                          │  commande_2                  │
                          │  ......                      │
                          │ done                         │
                          └──────────────────────────────┘
    

    L'instruction 'while' exécute la commande spécifiée comme test de boucle et teste son code de retour.

    Tant que le code de retour est 'true' (vrai) les commandes spécifiées dans la boucle entre 'do' et 'done' sont exécutées et l'on recommence le cycle.

    Exemple de boucle 'while' affichant ligne par ligne les arguments d'appel
       ┌───────────────┐
       │ while test $1 │  "test $1" ::= Test si la chaîne est vide ou non
       │ do            │
       │   echo $1     │
       │   shift       │  "shift"   ::= Entraîne un décalage '$n => $n-1'
       │ done          │
       └───────────────┘
    

    Exemple de boucle infinie
       ┌────────────┐
       │ while true │
       │ do         │
       │   ......   │   Pour sortir par programme de cette boucle voir 'break'
       │ done       │
       └────────────┘
    




     3.3.3.13 : until ... do ... done  BOUCLE UNTIL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                          ┌──────────────────────────────┐
       Boucle until   ::  │ until commande_test_boucle   │
                          │ do                           │
                          │  commande_1                  │
                          │  commande_2                  │
                          │  ......                      │
                          │ done                         │
                          └──────────────────────────────┘
    

    L'instruction 'until' exécute la commande spécifiée comme test de boucle et teste son code de retour.

    Tant que le code de retour est 'false' (faux) les commandes spécifiées dans la boucle entre 'do' et 'done' sont exécutées et l'on recommence le cycle.

    Exemple de boucle 'until' affichant ligne par ligne les arguments d'appel
       ┌───────────────────────────┐
       │ until test ! ${1-""}      │  Le test est ici plus compliqué car il
       │ do                        │  faut gérer le cas où l'on a atteint la
       │  echo $1                  │  fin des arguments et faire une
       │  shift                    │  substitution d'un argument non défini par
       │ done                      │  une chaîne vide afin de ne pas avoir
       └───────────────────────────┘  d'erreur sur l'exécution du test.
    

    Il est évident que dans ce cas une boucle 'while' est plus simple mais lorsque les tests ne se font plus sur des variables d'environnement mais sur des commandes la boucle 'until' se révèle aussi facile à utiliser qu'une boucle 'while'.

    Exemple de boucle infinie
       ┌─────────────┐
       │ until false │
       │ do          │
       │   ......    │  Pour sortir par programme de cette boucle voir 'break'
       │ done        │
       └─────────────┘
    




     3.3.3.14 : break continue  DEBRANCHEMENT/BOUCLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Dans les boucles 'while ....', 'until ..... ' ou 'for ......' on pourra utiliser :

        ┌───────┐
        │ break │       ::=  Pour sortir de la boucle
        └───────┘
    

        ┌──────────┐
        │ continue │    ::=  Pour ne pas exécuter les instructions qui suivent
        └──────────┘           et remonter en début de boucle.
    

        ┌─────────┐
        │ break n │     ::=  Sortie de la boucle de nième niveau supérieur
        └─────────┘
    

        ┌────────────┐
        │ continue n │  ::=  Pour remonter en début de boucle de nième niveau
        └────────────┘         supérieur.
    

    Si n est égal à 0 ou à 1 il n'est pas nécessaire de l'indiquer car par défaut on sort de la boucle en cours.




     3.3.3.15 : true false  FONCTIONS LOGIQUES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Il existe des commandes 'true' et 'false' qui permettent de retourner des valeurs 'vrai' ou 'faux' comme en 'C' il existe des constantes 'TRUE' et 'FALSE'.

       ┌──────┐
       │ true │  ::=  N'exécute rien et retourne toujours '0'
       └──────┘
    

       ┌───────┐
       │ false │ ::=  N'exécute rien et retourne toujours quelque chose
       └───────┘        de différent de zéro.
    

    NOTE : En 'C' la constante 'TRUE' est égale à 1 la constante 'FALSE' est égale à 0.

    Ceci semble paradoxal, mais en fait, les instructions 'if ....' , 'while ....', 'until .... ' travaillent à l'inverse du 'C' car :

    - en SHELL on teste le code retour d'une commande (0 :: VRAI alors que différent de zéro ::= FAUX).

    - en 'C' on évalue une expression logique où Egal à 0 ::= FAUX et Différent de zéro ::= VRAI.




     3.3.3.16 : expr EXPRESSIONS ARITHMETIQUE/LOGIQUE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre est consacré à la commande 'expr expression ...'.

    Cette commande peut-être considérée comme obsolète car elle peut être être remplacée par la COMMANDE COMPOSEE ((expr)).

    Le détail de cette commande ne figure ici que pour les personnes confrontées à d'anciens scripts.

    Les nouveau utilisateurs peuvent faire l'impasse sur ce chapitre et passer directement au chapitre suivant.

    NOM
       ┌───────────────────────────────────────────────────────────────┐
       │ expr ::= Evaluation d'arguments traités comme des expressions │
       └───────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
       ┌───────────────────────┐
       │ expr expression ....  │
       └───────────────────────┘
    

    DESCRIPTION

    Les arguments spécifiés sont traités comme des expressions et ces expressions sont évaluées de la gauche vers la droite.

    Après évaluation le résultat est affiché sur la sortie standard.

    ATTENTION : il faudra bien distinguer la valeur affichée (résultat logique) et le code de retour.

    En effet l'affichage est constitué du :

          ┌──────────────────────────────────┐
          │ Résultat logique de l'expression │
          └──────────────────────────────────┘
    

    alors que le code de retour est :

          ┌────────────────────────────────────────────────────────────────────┐
          │  0 ::= Si l'expression est correcte, non nulle, différente de 0.   │
          │  1 ::= Si l'expression est correcte, et nulle ou égale à 0.        │
          │  2 ::= Si l'expression est incorrecte ou en cas de division par 0. │
          └────────────────────────────────────────────────────────────────────┘
    

    Chaque partie d'expression doit être séparée des autres par au moins un espace.

    Les caractères spéciaux du SHELL doivent être marqués par un '\'.

    Les chaînes de caractères contenant des espaces ou des caractères spéciaux devront être encadrées par des «'» ou des «'».

    Si l'on utilise des variables "$nom_variable", et que ces variables peuvent être vides, il est impératif d'encadrer le nom de la variable entre «"», pour que le résultat soit bien un argument vide et non pas considéré comme une absence d'argument (Dans ce cas il y a une erreur de syntaxe). En effet 'expr $toto = $titi' donnerait 'expr = ' après substitution par le SHELL des valeurs contenues dans les variables 'toto' et 'titi' vides.

    ATTENTION : En cas d'expression vide un '0' sera affiché sauf pour les expressions 'arg1 : arg2' où un opérande nul est affiché s'il n'y a pas eu de correspondance entre 'arg1' et l'expression régulière spécifiée en 'arg2'.

    Les valeurs numériques sont des valeurs entières et peuvent être précédées par un signe '-' pour exprimer des valeurs négatives.

    Les entiers sont traités sur 32 bits.

    La taille d'une expression est limitée à 512 caractères.

    OPERATEURS LOGIQUES OU ARITHMETIQUES :

    Il existe plusieurs opérateurs (ou mots-clés).

    Lorsqu'un opérateur est un des caractères spéciaux du SHELL il devra être marqué avec un '\' ou encadrés par des «"» ou des «'».

    Cette liste est dans l'ordre des priorités croissantes.

    Les opérateurs de même priorité sont indiqués entre "{}".

       ┌─────────────┐
       │ arg1 │ arg2 │   (Attention au marquage ou encadrement du '|')
       └─────────────┘
    

    Affiche la première expression si celle-ci est non nulle ou différente de 0. Et dans le cas contraire affiche la deuxième expression. Si les deux sont nulles, alors affiche 0.

    Exemple avec la variable 'toto' non initialisée ou vide :

       ┌─────────────────────────────────────────────────────────────────────────────────┐
       │ expr "$TERM" \| "$toto"   ::=  Affiche le contenu de TERM    $?::=0             │
       │ expr "$toto" \| "$TERM"   ::=  Affiche le contenu de TERM    $?::=0             │
       │ expr "$toto" \| "$toto"   ::=  Affiche 0                     $?::=1             │
       └─────────────────────────────────────────────────────────────────────────────────┘
    

       ┌─────────────┐
       │ arg1 & arg2 │   (Attention au marquage ou encadrement du '&')
       └─────────────┘
    

    Affiche la première expression si aucune des deux n'est nulle ou égale à zéro. Dans le cas contraire affiche 0.

    Exemple avec la variable 'toto' non initialisée ou vide :

       ┌─────────────────────────────────────────────────────────────────────────────────┐
       │  expr "$TERM" \& "$toto"   ::=  Affiche 0                     $?::=1            │
       │  expr "$toto" \& "$TERM"   ::=  Affiche 0                     $?::=1            │
       │  expr "$toto" \& "$toto"   ::=  Affiche 0                     $?::=1            │
       │  expr "$TERM" \& "$SHELL"  ::=  Affiche le contenu de TERM    $?::=0            │
       └─────────────────────────────────────────────────────────────────────────────────┘
    

       ┌───────────────────────────────────────┐
       │ arg1 { =, >, >=, <, <=, != } arg2     │  Attention au marquage ou à
       └───────────────────────────────────────┘  l'encadrement des caractères
    

    (>,<,<=,>=) Affiche le résultat de la comparaison spécifiée :

    0 ::= Comparaison O.K.

    1 ::= Comparaison non O.K.

    Cette comparaison se fait :

    - entre entiers si les deux arguments sont des entiers.

    - de façon alphanumérique si au moins un des deux arguments n'est pas un entier.

       ┌─────────────────────────────────────────────────────────────────────────────────┐
       │ expr "$TERM" = "$XSDETERM"  ::=  Affiche 1 si TERM = XSDETERM  $?::=0           │
       │                                  Affiche 0 si TERM <> XSDETERM $?::=0           │
       │ expr $i \> 10 ::=  Affiche 1 si 'i' est un entier >10          $?::=0           │
       │               ::=  Affiche 0 si 'i' est un entier <=10         $?::=1           │
       │               ::=  Affiche 1 si 'i' est un alpha > "10"        $?::=0           │
       │               ::=  Affiche 0 si 'i' est un alpha <= "10"       $?::=1           │ 
       └─────────────────────────────────────────────────────────────────────────────────┘
    

       ┌────────────────────┐
       │ arg1 { +, - } arg2 │       arg1::=entier  et arg2::=entier
       └────────────────────┘
    

    Affiche le résultat de l'opération addition ou soustraction entre les arguments indiqués qui doivent être des entiers.

       ┌───────────────────────────────────────────────────────────────────┐
       │ expr 2 + 3   ::= Affiche 5                              $?::=0    │
       │ expr 3 - 3   ::= Affiche 0                              $?::=1    │
       └───────────────────────────────────────────────────────────────────┘
    

       ┌────────────────────────┐
       │ arg1 { *, /, % } arg2  │   arg1::=entier  et arg2::=entier
       └────────────────────────┘
    

    Affiche le résultat de la multiplication, division, ou le reste de la division des arguments indiqués qui doivent être des entiers.

    ATTENTION : Pour une multiplication l'opérateur devra être soit marqué avec un '\' ou être entre «"» ou «'».

       ┌─────────────────────────────────────────────────────────────────────────────────┐
       │ expr 2 \* 3   ::= Affiche 6                                    $?::=0           │ 
       │ expr 2 \* 0   ::= Affiche 0                                    $?::=1           │ 
       │ expr 2 \ 0    ::= Affiche 'expr : division by zero'            $?::=2           │ 
       └─────────────────────────────────────────────────────────────────────────────────┘
    

       ┌─────────────┐
       │ arg1 : arg2 │    arg1::=Chaîne source    arg2::=Expression régulière
       └─────────────┘
    

    Recherche caractères/Extraction sous-chaînes par Expression Régulière :

    Compare le premier argument avec le second qui doit être une expression régulière au sens 'ed'. Mais chaque expression sera considérée comme commençant par '^' sans que l'on ait à le préciser. Ceci entraîne que l'expression régulière est considérée comme à rechercher depuis le début de l'argument 1.

    De plus, si l'on utilise une E.R. simple (sans '\(...\)'), 'expr' affiche le nombre d'octets correspondant à l'expression régulière (0=Pas d'occurence).

    ATTENTION : Il ne s'agit pas du nombre d'occurences mais du nombre d'octets trouvés comme correspondant à l'expression régulière spécifiée.

    Exemples :

     ┌─────────────────────────────────────────────────────────────────────────┐
     │expr abcdefgh : ab        ::= Affiche 2                           $?::=0 │
     │expr abcdefgh : cd        ::= Affiche 0 (cd n'est pas en début)   $?::=1 │
     │expr abcdefgh : ..cd      ::= Affiche 4 (occurence de 'abcd')     $?::=0 │
     │                              ( recherche de 'cd' en position 3,4)       │
     │expr abcdefgh : '.*cd'    ::= Affiche 4 (occurence de 'abcd')     $?::=0 │
     │                              ( recherche de 'cd' dans 'arg1')           │
     │expr abcdefgh : '.*'      ::= Affiche 8 (::=length)               $?::=0 │
     │expr abcdefgh : '.*[A-Z]' ::= Affiche 0 (pas de majuscule)        $?::=1 │
     │expr Abcdefgh : '[A-Z]'   ::= Affiche 1 (occurence de 'A')        $?::=0 │
     │expr abCdefgh : '[A-Z]'   ::= Affiche 0 (pas de majusc.en pos.1)  $?::=1 │
     │expr abCdefgh : '.*[A-Z]' ::= Affiche 3 (occurence de 'abC')      $?::=0 │
     │expr abCdefGh : '.*[A-Z]' ::= Affiche 7 (occurence de 'abCdefG')  $?::=0 │
     └─────────────────────────────────────────────────────────────────────────┘
    

    Si l'on désire obtenir la partie de chaîne correspondant à une partie de l'E.R. on peut encadrer la partie désirée de l'E.R. entre '\(' et '\)'.

    Si l'on spécifie un certain nombre de '.' cela indique le nombre de caractères désirés.

    Si l'on spécifie d'autres caractères que le '.' entre ces '\(' et '\)' ils ont la même signification que dans une E.R. simple mais 'expr' retourne comme dans le cas précédant la chaîne qui correspond à cette fraction d'E.R..

    Comme 'expr arg1 : arg2' est prévu pour retourner une chaîne et une seule il ne peut y avoir qu'un seul encadrement entre '\(' et '\)'.

    On peut donc faire avec cette formulation des extractions de sous-chaînes dans des chaînes données en argument. Exemples :

      ┌──────────────────────────────────────────────────────────────────┐
      │ expr abcdefgh : '\(..\)'       ::= Affiche ab             $?::=0 │
      │ expr abcdefgh : '...\(..\)'    ::= Affiche de             $?::=0 │
      │ expr abcdefgh : '..\(...\)'    ::= Affiche cde            $?::=0 │
      │ expr abcdefgh : '.*cde\(..\)'  ::= Affiche fg             $?::=0 │
      │ expr abcdefgh : '\(.*\)cde\'   ::= Affiche ab             $?::=0 │
      │ expr abcdefgh : '\(.*\)def\'   ::= Affiche abc            $?::=0 │
      │ expr abcdefgh : '\(.*bc\)'     ::= Affiche abc            $?::=0 │
      │ expr abcdefgh : '\(.*def\)'    ::= Affiche abcdef         $?::=0 │
      └──────────────────────────────────────────────────────────────────┘
    

    EXEMPLES

    Ajouter 1 à la variable SHELL 'a' : a=`expr $a + 1`

    Multiplier la variable SHELL 'a' par 2 : a=`expr $a '*' 2` Noter le '*' pour éviter que ce caractère soit interprété par le SHELL.

    Expressions multiples :

            ┌───────────────────────┐     ┌────────────┐     ┌────┐
            │ expr 21 + 9 '*' 2 / 6 │ ::= │ 21+(9*2)/6 │ ::= │ 24 │
            └───────────────────────┘     └────────────┘     └────┘
    

    Comparaisons de deux variables expr "$toto" = "$titi" ::= Affiche 1 si égalité Noter l'encadrement entre «"» pour éviter un problème de syntaxe si une des variables 'toto' ou 'titi' est vide.

    L'exemple suivant reproduit ce que fait la commande 'basename' qui permet d'obtenir le nom d'un fichier à partir d'un path complet.

    Exemple : pour '/usr/abc/fichier' donné en argument on doit obtenir
         'fichier' :    ┌─────────────────────────────┐
                        │ expr $a : '.*/\(.*\)' \| $a │
                        └─────────────────────────────┘
    

    Mais un problème peut se poser si '$a' contient un seul caractère '/' car dans ce cas l'exemple précédent aboutirait à une erreur de syntaxe car le '/' serait considéré comme opérateur de division mais sans argument. Une solution plus élégante consisterait à ajouter deux '/' devant le contenu de la variable afin de lever l'ambiguïté.

                   ┌─────────────────────────┐
                   │ expr //$a : '.*/\(.*\)' │
                   └─────────────────────────┘
    

    Utilisation pour obtenir la taille du contenu d'une variable :

                                                     ┌──────────────────┐
      Nombre de caractères dans une variable SHELL : │ expr $VAR : '.*' │
                                                     └──────────────────┘
    

    VOIR AUSSI
       ┌───────────────┐
       │ ed(1), sh(1). │
       └───────────────┘
    

    DIAGNOSTICS 'expr' retourne les codes suivants :

     ┌──────────────────────────────────────────────────────────────┐
     │ 0    Si l'expression n'est ni nulle ni égale à 0 .           │
     │ 1    Si l'expression est nulle ou égale à 0.                 │
     │ 2    Pour des expressions invalides ou une division par zéro │
     └──────────────────────────────────────────────────────────────┘
    

    Erreur de syntaxe : Si on utilise des opérateurs arithmétiques sur des variables ne contenant pas des valeurs entières pures.

    ATTENTION : Ne pas confondre la valeur affichée et le code de retour.

    NOTES Après traitement des arguments par le SHELL, 'expr' ne fait plus de différence entre un opérateur et un opérande mais examine seulement les valeurs de ceux-ci.

    Si $a contient '=' alors la commande :

               ┌───────────────┐                          ┌────────────┐
               │ expr $a = '=' │  sera interprétée comme  │ expr = = = │
               └───────────────┘                          └────────────┘
    

    Si l'on désire lever l'ambiguïté il faut ajouter un caractère non ambigu à chaque opérande et utiliser :

               ┌───────────────┐
               │ expr X$a = X= │
               └───────────────┘
    




     3.3.3.17 : ((expression_arithmetique))  COMMANDE COMPOSEE 
        EXPRESSIONS ARITHMETIQUE/LOGIQUE
      Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre est consacré à la commande composée (( expr )) .

    Elle remplace avantageusement la commande expr EXPRESSIONS ARITHMETIQUE/LOGIQUE.

    ┌────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────┐
    │   Opérateurs par priorité décroissante                 │                                                                          │
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   - +                                                  │  Opérateur unaire plus ou moins  (+10, -5, ....)                         |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   ! ~                                                  │  Négation logique ou bit à bit                                           |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   **                                                   │  Exponentiation                                                          |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   *  /  %                                              │  Multiplication, division, reste de la division                          |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   <<  >>                                               │  Décalage arithmétique                                                   |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   <  <=   >=  >                                        │  Comparaison                                                             |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   ==  !=                                               │  Egalité ou différence                                                   |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   &                                                    │  ET bit à bit                                                            |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   ^                                                    │  OU exclusif bit à bit                                                   |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   |                                                    │  OU bit à bit                                                            |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   &&                                                   │  ET logique                                                              |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   ||                                                   │  OU logique                                                              |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   expr1?expr2:expr3                                    │  Affectation conditionnelle si expr1 alors résultat = expr2 sinon expr3  |
    ├────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤
    │   =  *=  /=  %=  +=  -=  <<=  >>=  &=  ^=  |=          │  Assignation simple (a=3) et étendues (a+=3, ...)                        │
    └────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────┘
    

    Il est à noter que la syntaxe d'une expression arithmétique est beaucoup plus simple entre (( )) que celles définissables avec expr.

    Avec expr on ne pouvait définir qu'une opération à la fois et les opérateurs comme '*', '|' devaient impérativement être marqués.

    Avec (( expression_arithmétique )), on pourra utiliser tous les opérateurs du 'C' ('=' pour une assignation simple et '==' pour une comparaison en égalité, ...).

    Il pourra y avoir plusieurs opérations arithmétiques, éventuellement, avec des parenthèses imbriquées.

    On pourra séparer par un ou plusieurs espaces (si on le désire) les opérandes et les opérateurs

    Il est à noter que l'on utilise que des opérandes, et le résultat sera tronqué s'il y a des décimales.

    Exemples avec des variables a=2 b=3 et c=5 :

           ┌───────────────────────────────────┬─────────────┬────────┐                   
           │ $ ((a+b+c))                       │       10    │    0   │
           │ $ ((a+b-c))                       │        0    │    1   │
           └───────────────────────────────────┴─────────────┴────────┘                   
    

    Dans cet exemple on exécute la commande composée directement au prompt, donc elle n'affiche rien mais elle effectue le calcul et se termine avec un code de retour qui dépend du résultat.

           ┌─────────────────────────────┬─────────────┐                   
           │ $ ((100/6))                 │       16    │
           │ $ ((100/3))                 │       33    │
           └─────────────────────────────┴─────────────┘                   
    

    Si l'on désire assigner à une valeur on pourra le faire de deux manières différentes :

           ┌──────────────────────────────────┬────────────────────────────────────────────┐                   
           │ $ r=$(((a+b)*c))                 │ r contiendra 25                            │
           │ $ ((r=((a+b)*c))                 │ r sera modifié par l'expression elle même  │
           └──────────────────────────────────┴────────────────────────────────────────────┘                   
    




     3.3.3.18 : FONCTIONS SHELL (SOUS-PROGRAMMES)   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Une fonction peut se définir dans un script SHELL sous la forme :

                    ┌─────────────────┐    ┌─────────────────────────────────┐
      fonction  ::= │ nom_fonction () │ ou │ nom_fonction () { liste_cde ; } │
                    │ { instruct_1    │    └─────────────────────────────────┘
                    │   instruct_2    │
                    │   .........     │
                    │ }               │
                    └─────────────────┘
    

    Une fonction permet de définir une série d'instructions (ou de commandes) à exécuter lors de chaque appel de la fonction dans la suite du script.

    Comme le SHELL est un interpréteur de commandes il est nécessaire de :

    - Définir les fonctions en début de script et le script proprement dit à la suite de ces fonctions.

    - Au moins avant leur utilisation par le script lui-même.

    Le SHELL reconnaît les fonctions lors de l'interprétation du script, mais ne les exécute que lors de leur appel dans le corps principal du script.

    En fait il s'agit de la même définition de fonction que dans le chapitre 'nom_fonction () { cde1 ; ... ;} FONCTION', seulement les fonctions définies dans le script ne sont connues que de ce script. En fait une fonction définie sous SHELL est utilisable dans le processus où elle a été définie et il y a bien équivalence entre ces deux définitions.

    L'appel d'une fonction dans le corps se fait avec son nom suivi éventuellement d'arguments qui seront récupérables dans la fonction avec $1, $2, ... ou $*.

      ┌────────────────────────┐      ┌────────────────────────────────────────┐
      │ nom_fonction arg1 arg2 │  ::= │ Appel fonction avec deux arguments que │
      └────────────────────────┘      │  la fonction pourra récupérer avec     │
                                      │  '$1' et '$2'.                         │
                                      └────────────────────────────────────────┘
    

    Le code retour d'une fonction se positionne avec la commande 'return'.

                                                     ┌────────────┐
       Positionnement code retour d'une fonction ::= │ return [n] │
                                                     └────────────┘
    

    Ce code de retour pourra être utilisé dans des expressions conditionnelles du genre 'if nom_fonction arg1 ... '. Une valeur de retour égale à 0 est considérée comme satisfaisant à la condition définie, alors que toute valeur différente de 0 est considérée comme ne satisfaisant pas à cette condition. Pour plus de détail sur les expressions conditionnelles, voir le chapitre 'INSTR.CONDITIONNELLES'.

                     ┌─────────────────────────────────────────┐
       Exemple   :   │  fct1 ()                                │
                     │  { .......                              │
                     │    ..........                           │
                     │    return 0                             │
                     │  }                                      │
                     │                                         │
                     │  fct2 ()                                │
                     │  { .......                              │
                     │    .......                              │
                     │  }                                      │
                     │                                         │
                     │  #début logique du script               │
                     │  ......                                 │
                     │  fct1 arg1 arg2 # appel fonction 'fct1' │
                     │  .......                                │
                     │  .....                                  │
                     │  fct2 arg1      # appel fonction 'fct2' │
                     │  .......                                │
                     │  .....                                  │
                     │  fct1 arg1 arg2 # appel fonction 'fct1' │
                     │  .......                                │
                     └─────────────────────────────────────────┘
    




     3.3.4 : RECAPITULATIF COMMANDES INTERNES DU SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Il existe en SHELL des commandes internes qui se distinguent des autres commandes par le fait qu'elles sont exécutées dans le processus courant et non pas comme les commandes externes dans un processus fils.

    Ces commandes sont détaillées dans des chapitres différents selon leur utilisation logique (PROGRAMMATION, GESTION ENVIRONNEMENT, etc...)

    Ce chapitre a pour objet de récapituler la liste de ces commandes internes et de vous indiquer dans quel chapitre vous trouverez le détail de leur fonctionnement.

     ┌──────────┬──────────────────────────────────┬────────────────────────────────┐
     │ cd       │ Changement de répertoire courant │ COMMANDES ENVIRONNEMENT        │
     │ echo     │ Affichage d'arguments            │ COMMANDES AFFICHAGE            │
     │ eval     │ Evaluation arg.et exécution      │ EXECUTION COMMANDES            │
     │ exec     │ Exécution en remplacement        │ SHELL LANGAGE DE PROGRAMMATION │
     │ exit     │ Sortie d'un SHELL/script SHELL   │ SHELL LANGAGE DE PROGRAMMATION │
     │ export   │ Exportation variables env.       │ VARIABLES D'ENVIRONNEMENT      │
     │ getopts  │ Analyse options lignes commande  │ SHELL LANGAGE DE PROGRAMMATION │
     │ hash     │ Gestion table 'hash'             │ COMMANDES ENVIRONNEMENT        │
     │ login    │ Nouvelle session de 'login'      │ GESTION UTILISATEURS           │
     │ newgrp   │ Chgt de groupe réel/effectif     │ GESTION UTILISATEURS           │
     │ pwd      │ Affichage nom répertoire courant │ COMMANDES ENVIRONNEMENT        │
     │ read     │ Lecture données sur entrée std   │ SHELL LANGAGE DE PROGRAMMATION │
     │ readonly │ Protection modification variable │ VARIABLES D'ENVIRONNEMENT      │
     │ set      │ Paramétrage options SHELL        │ SHELL LANGAGE DE PROGRAMMATION │
     │ shift    │ Décalage arguments               │ SHELL LANGAGE DE PROGRAMMATION │
     │ test     │ Tests logiques fichiers/chaînes  │ SHELL LANGAGE DE PROGRAMMATION │
     │ times    │ Temps utilisat./système consommé │ GESTION DU TEMPS               │
     │ trap     │ Protection/Masquage signaux      │ SHELL LANGAGE DE PROGRAMMATION │
     │ type     │ Affichage type de commandes      │ COMMANDES ENVIRONNEMENT        │
     │ ulimit   │ Gestion taille maximum fichier   │ COMMANDES ENVIRONNEMENT        │
     │ umask    │ Masque droits fichiers           │ COMMANDES ENVIRONNEMENT        │
     │ unset    │ Suppression de variable d'env.   │ VARIABLES D'ENVIRONNEMENT      │
     │ wait     │ Attente fin cdes arrière plan    │ CONTROLE PROCESSUS             │
     └──────────┴──────────────────────────────────┴────────────────────────────────┘
    




     3.4 : GESTION DES TÂCHES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    ce chapitre sera consacré aux tâches en arrière plan.




     3.4.1 : COMMENT LANCER UNE TÂCHE EN ARRIERE PLAN   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

        ┌─────────────────────┐  
        │ commande &          │
        │ nohup commande &    │
        └─────────────────────┘
    

    Lors du lancement en arrière plan d'une commande, le shell affiche le numéro de tâche, ainsi que le numéro de processus sous la forme :

        [j] pppp     j ::= no de tâche et  pppp := numéro de processus.
    

    Lorsque la tâche se termine le shell affiche :

        [j]+ Done nom_commande  j ::= numéro de tâche
    

    Sans nohup l'affichage d'une commande en arrière plan sans redirection se fait sur les sorties standard et erreur. Ce qui peut perturber l'affichage normal d'une commande lancée en interactif et dont les affichages se mélangeront avec ceux de la tâche en arrière plan.

    Il est à noter que l'affichage de la fin de tâche se fait presque en temps réel (pour ne pas perturber l'affichage d'une autre commande en cours).

    La fin de commande s'affiche en fait à chaque fois que le SHELL affiche l'invite de commande (prompt).

    La différence entre un appel "commande &" et "nohup commande &" se situe sur les redirections et la survie de la tâche si le processus qui a lancé la tâche se termine.

    Par défaut la commande 'nohup' redirige les sorties standard et erreur dans un fichier 'nohup.out'. Ce fichier 'nohup.out' sera créé ou agrandi dans le répertoire courant si cela est possible . Dans le cas contraire il sera créé dans $HOME.

    Si l'on désire une redirection dans un fichier spécifique :

        ┌───────────────────────────────────────┐  
        │ commande >nom_fichier 2>&1 &          │
        │ nohup commande >nom_fichier &         │
        └───────────────────────────────────────┘
    

    Exemple pour la survie d'une tâche :

    Un utilisateur ouvre une session (ou un terminal) et veut exécuter une tâche en arrière plan.

          commande & ::= La tâche lancée en arrière plan sera arrêtée si l'utilisateur ferme sa session ou son terminal.
    
          nohup commande & ::= La tâche lancée en arrière plan survivra (continuera à s'exécuter) même si l'opérateur ferme son terminal.
    

    Une commande lancée en arrière plan pourra être repassée en avant plan puis repassée en arrière plan avec les commandes bg ou §8 1§fg (voir plus loin).

    L'affichage des tâche en cours se fait avec la commande jobs.

    Si vous essayez de quitter bash avec des jobs suspendus, le shell affichera un avertissement.

    La commande jobs permet de vérifier leurs états.

    Une fois cette commande invoquée, ou si vous essayez à nouveau de quitter le shell immédiatement, il n'y aura plus d'avertissement, et les jobs suspendus seront définitivement terminés.




     3.4.2 : Suspension en arrière plan d'une commande lancée 
        normalement.
      Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Lors du lancement d'une commande, il se peut que l'on s'appercevoir que cette tâche aurait du être lancée en arrière plan. On peut évidemment ouvrir une autre fenêtre (un autre terminal) pour pouvoir lancer autre chose, mais sur un site distant cela peut être pénalisant.

    Une autre raison peut être que la tâche en cours se révèle très gourmande en ressource et que l'on désire la suspendre pour pouvoir la reprendre par la suite en arrière plan ou en la faisant revenir en avant plan.

    Il suffit de saisir la combinaison <CTRL><Z> pour que la commande en cours passe en arrière plan et soit suspendue.

    Le résultat de <CTRL><Z> entraine un affichage de la forme suivante :

    [j]+  Stopped   nom_commande      j::=numéro de tâche  Stopped ::= Mention que la tâche est bien suspendue.
    

    Une tâche ainsi envoyé en arrière plan ET suspendue pourra être ré-activée (en arrière plan) ou repassée en avant plan avec les commandes bg ou fg (voir plus loin).

    L'affichage des tâche en cours se fait avec la commande jobs.




     3.4.3 : jobs Affichage des tâches et de leur état   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La commande jobs affiche la liste des tâches et leur état :

    OPTIONS
       -l Affichage du numéro de processus  
       -n N'affiche que les tâches dont l'état a changé depuis la dernière notification
       -p N'affiche que les numéro de processus (pas de numéro de tâche pas d'état des tâche).
       -r N'affiche que les tâches en cours d'exécution (Running)
       -s N'affiche que les tâches suspendues (Stopped)
    

    Exemples (si l'on a lancé commande_1, commande_2 et commande_3 ) :

          jobs 
          [1]   Running    nom_commande_1 
          [2]-  Stopped    nom_commande_2 
          [3]+  Stopped    nom_commande_2 
    
          jobs -l
          [1]   12345 Running    nom_commande_1
          [2]-  12465 Stopped    nom_commande_2
          [3]+  12465 Stopped    nom_commande_3
    

    Le job marqué d'un '+' est le job courant, celui sur lequel s'appliqueront par défaut les commande bg, ou fg ne spécifiant pas de numéro de job.

    Le job marqué d'un '-' est le job précédent le job courant.

    Le job courant est le dernier job arrêté alors qu'il se trouvait en avant-plan.

    On pourra référencer le job courant avec %% ou %+ et le job précédent avec %-




     3.4.4 : bg et fg Passage d'arrière en avant plan et réactivation 
        d'une tâche suspendue
      Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Rappel : Si un tâche a été exécutée en avant plan et que l'on désire la placer en arrière plan (où elle arrivera suspendue), il suffira de faire <CTRL><Z>.

    Utillisation des commandes fg ou bg (fg::=Avant plan, bg::=Arrière plan) :

       bg no_job Ré-active une tâche suspendue en la laissant en arrière plan : 
    

    Pour repasser une tâche en arrière plan en avant plan :

       fg no_job    Si la tâche était suspendue elle redevient active en passant en avant plan.
       fg no_job &  Active la tâche mais en arrière plan  
    

    Il existe des caractères spéciaux pour spécifier un numéro de job Un job référence avec un des cas caractères et interprété comme 'fg j'
       %j réference le job 'j'. Donc '%1',  sans autre commande, est synonyme de "fg %1".  
    
       %% et %+ référencent le job courant du shell. Donc sans commande (bg ou fg) %% ou %+ sont synonymes de
                  démarrage en avant plan du job courant
    
       %- réference le job 'j'. Donc '%1' sans autre commande est synonyme de "fg %1".  
    
       %prefixe réference le job dont la commande commence par le préfixe spécifié. 
                S'il y a plus d'une commande commençant par ce radical, le shell refusera cette ambiguïté.  
    
       %?critère réference le job dont la commande contient par le critère spécifié. 
                S'il y a plus d'une commande contenant ce critère, le shell refusera cette ambiguïté.  
    




     4 : EDITEURS SOUS UNIX   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre sera consacré aux éditeurs sous unix et à l'ancêtre des éditeurs 'vi'.

    Quand l'on dispose d'une interface graphique, on dispose d'éditeurs graphiques de qualité et d'utilisation relativement intuitive.

    On ne peut pas dire que 'vi' soit intuitif, mais son avantage est de fonctionner dans un environnement dégradé et d'être universel.

    'vi' a donnée naissance à des clones très intéressants (vim mode texte, et surtout gvim mode graphique'). 'gvim' est idéal pour débuter car disposant d'une interface graphique, il devient facile faire des commandes à partir de la barre de menu (Exemple : Fichier + Sauver sans passer par la commande ':wq' de vi).

    Mais plus on utilisera gvim plus on aura intérêt à apprendre les commandes natives de 'vi' qui pourraient alors être considérées comme des raccourcis à des actions dans un menu.




     4.1 : vi  EDITEUR PLEINE PAGE BASE SUR 'ex'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
     ┌─────────────────────────────────────────────────────────────────────────┐
     │vi ::=  Editeur pleine page basé sur les commandes de traitement de 'ex'.│
     └─────────────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
     ┌─────────────────────────────────────────────────────────────────────────┐
     │vi [ options ] fich...                                                   │
     └─────────────────────────────────────────────────────────────────────────┘
    

    DESCRIPTION 'vi' ('visual') est un éditeur 'pleine page' basé sur un éditeur 'ligne' sous-jacent appelé 'ex'. Il est possible d'appeler des commandes de 'ex' à l'intérieur de 'vi' et inversement.

    L'editeur 'ex' est un éditeur ligne à ligne qui n'a plus guère d'utilisation sauf si le type de terminal (variable TERM) est inconnu ou perturbé.

    Les modifications apportées au fichier par des commandes sont affichées en temps réel sur l'écran.

    Des options (Comme la numérotation de lignes, ou le démarrage d'une nouvelle ligne, etc...) sont communes à 'ex' et à 'vi'.

    En utilisant 'vi' la position du curseur sur l'écran indique la position courante dans le fichier.

    OPTIONS D'APPEL Les options suivantes sont interprétées par 'vi' sont :

    +[num] Place le curseur sur la ligne "num" dans le premier fichier. Si "num" est omis, le curseur sera placé sur la dernière ligne.

    +/{motif} Place le curseur sur la première occurence de {motif} dans le premier fichier. Voir ":help search-pattern" pour connaître les motifs de recherches disponibles.

    +{commande} -c {commande} Exécute {commande} après la lecture du premier fichier. {commande} est interprétée comme une commande Ex. Si la {commande} contient des espaces, elle doit être entourée de doubles-apostrophes (cela dépend du shell utilisé). Exemple: Vim "+set si" main.c Note : vous pouvez utiliser jusqu'à 10 commandes "+" ou "-c".

    -S {fichier} Source {fichier} après la lecture du premier fichier. C'est équivalent à -c "source {fichier}". {fichier} ne peut pas débuter par un '-'. Si {fichier} est omis, "Session.vim" est utilisé (cela ne fonctionne que si -S est le dernier argument).

    --cmd {commande} Comme "-c", mais la commande est exécutée juste avant de traiter les fichiers vimrc. Vous pouvez utiliser jusqu'à 10 de ces commandes, indépendamment des commandes "-c".

    -A Si Vim a été compilé avec le support de la fonctionnalité ARABIC pour l'édition de fichiers de droite à gauche et les claviers arabes, cette option lance Vim en mode Arabe, c.-à-d. que l'option 'arabic' est activée. Sinon, un message d'erreur est émis et Vim quitte.

    -b Mode Binaire. Active plusieurs options pour permettre l'édition d'un fichier binaire ou exécutable.

    -C Compatible. Active l'option 'compatible'. Vim se comportera alors quasiment comme Vi, même s'il existe un fichier .vimrc.

    -d Démarre en mode Diff. Deux ou trois noms de fichiers doivent être spécifiés. Vim ouvrira alors tous les fichiers et affichera leurs différences. Fonctionne comme vimdiff(1).

    -d {périph} Ouvre {périph} pour l'utiliser comme terminal. Uniquement sur Amiga. Exemple: "-d con:20/30/600/150".

    -D Debogage. Passe en mode Débogage lors de l'exécution de la première commande d'un script.

    -e Démarre Vim en mode Ex, comme si l'exécutable s'appelait "ex".

    -E Démarre Vim en mode Ex amélioré, comme si l'exécutable "exim" avait été invoqué.

    -f Premier-plan (Foreground). Pour la version graphique, Vim ne forke pas et ne se détache pas du shell dans lequel il a été invoqué. Sur Amiga, Vim n'est pas relancé pour ouvrir une nouvelle fenêtre. Cette option est utile quand Vim est exécuté par un programme qui attend la fin de la session d'édition (par exemple mail). Sur Amiga, les commandes ":sh" et ":!" ne fonctionneront pas.

    --nofork Premier-plan (Foreground). Pour la version graphique, Vim ne forkera pas et ne se détachera pas du shell dans lequel il a été lancé.

    -F Si Vim a été compilé avec le support de la fonctionnalité FKMAP pour l'édition de fichiers de droite à gauche et les claviers farsi, cette option lance Vim en mode Farsi, c.-à-d. avec les options 'fkmap' et 'rightleft' activées. Sinon, un message d'erreur est émis et Vim quitte.

    -g Si Vim a été compilé avec le support de l'IHM graphique, cette option active l'IHM graphique. Si le support n'a pas été compilé, un message d'erreur est émis et Vim quitte.

    -h Donne une aide succinte sur les arguments et les options de la ligne de commande. Après cela, Vim quitte.

    -H Si Vim a été compilé avec le support de la fonctionnalité RIGHTLEFT pour l'édition de fichiers de droite à gauche et les claviers hébreu, cette option lance Vim en mode Hebreu, c.-à-d. avec les options 'hkmap' et 'rightleft' activées. Sinon, un message d'erreur est émis et Vim quitte.

    -i {viminfo} Lorsque l'utilisation d'un fichier viminfo est activée, cette option indique le nom de fichier à utiliser à la place de "~/.viminfo" par défaut. Il est possible d'empêcher l'utilisation d'un fichier ".viminfo", en spécifiant le nom de fichier "NONE".

    -L Comme -r.

    -l Mode Lisp. Active les options 'lisp' et 'showmatch'.

    -m Empêche la modification des fichiers. Désactive l'option 'write'. Vous pouvez toujours modifier le tampon, mais il vous sera impossible d'écrire le fichier.

    -M N'autorise aucune modification. les options 'modifiable' et 'write' sont desactivées, de sorte que les changements ne sont pas autorisés et que les fichiers ne peuvent pas être écrits. Note : ces options peuvent être activées pour autoriser les modifications.

    -N Mode Non-compatible. Désactive l'option 'compatible'. Cela améliorera le comportement de Vim , mais il sera moins conforme à celui de Vi, même s'il n'existe aucun fichier ".vimrc".

    -n N'utilise pas de fichier d'échange (swapfile). Le recouvrement après un plantage sera impossible. Utile pour éditer un fichier sur un support très lent (disquette par ex.). Également activable avec ":set uc=0". Il est possible de l'annuler avec ":set uc=200".

    -nb Devient un serveur d'édition pour NetBeans. Consulter la documentation à ce sujet pour davantage de détails.

    -o[N] Ouvre N fenêtres les unes au-dessus des autres. Quand N est omis, ouvre une fenêtre pour chaque fichier.

    -O[N] Ouvre N fenêtres côte à côte. Quand N est omis, ouvre une fenêtre pour chaque fichier fichier.

    -p[N] Ouvre N onglets. Quand N est omis, ouvre un onglet pour chaque fichier fichier.

    -R Mode Lecture-Seule. Active l'option 'readonly'. Vous pouvez toujours éditer le tampon, mais il vous sera impossible de d'écraser accidentellement un fichier. Si vous voulez écraser un fichier, ajoutez un point d'exclamation à la commande Ex, comme dans ":w!". L'option -R impose l'option -n (voir ci-dessus). L'option 'readonly' peut être désactivée avec ":set noro". Voir ":help 'readonly'".

    -r Donne la liste des fichiers d'échange, avec des informations pour les utiliser à des fins de recouvrement.

    -r {file} Mode Recouvrement. Utilise le fichier d'échange pour récouvrer d'une session d'édition plantée. Le fichier d'échange est un fichier avec le même nom que le fichier texte, suivi du suffixe ".swp". Voir ":help recovery".

    -s Mode Silencieux. Disponible uniquement quand Vim est lancé en tant que "ex" ou quand l'option "-e" a été spécifiée avant l'option "-s".

    -s {scriptEntrée} Lit le fichier de script {scriptEntrée}. Les caractères du fichier sont interprétés comme si vous les tapiez. La commande ":source! {scriptEntrée}" donne le même résultat. Si la fin du fichier est atteinte avant que l'éditeur quitte, les caractères suivants sont lus depuis le clavier.

    -T {terminal} Indique à Vim le nom du terminal utilisé. Cela n'est requis que lorsque la détection automatique échoue. Le {terminal} devrait être connu de Vim (intégré) ou défini dans le fichier termcap ou terminfo.

    -u {vimrc} Utilise les commandes du fichier {vimrc} pour les initialisations. Toutes les autres initialisations sont omises. À utiliser pour éditer un type de fichiers particulier. Cela permet aussi d'omettre toute initialisation en spécifiant le nom de fichier "NONE". Voir ":help initialization" dans Vim pour davantage de détails.

    -U {gvimrc} Utilise les commandes du fichier {gvimrc} pour l'initialisation de l'IHM graphique. Toutes les autres initialisations graphiques sont omises. Cela permet aussi d'omettre toute initialisation graphique en spécifiant le nom de fichier "NONE". Voir ":help gui-init" dans Vim pour davantage de détails.

    -V[N] Mode Verbeux. Donne des messages à propos des fichiers sourcés, ainsi que sur la lecture et les écritures dans le fichier viminfo. le nombre optionnel N précise la valeur de l'option 'verbose' (10 par défaut).

    -v Démarre Vim en mode Vi, comme si l'exécutable s'appelait "vi". Cela n'a d'effet que si l'exécutable invoqué est "ex".

    -w {scriptSortie} Tous les caractères que vous tapez sont enregistrés dans le fichier {scriptSortie}, jusqu'à ce que vous quittiez Vim. C'est utile quand vous voulez créer un fichier de script à utiliser avec "vim -s" ou ":source!". Si le fichier {scriptSortie} existe, les caractères sont ajoutés à la fin.

    -W {scriptSortie} Comme -w, mais un fichier existant sera écrasé.

    -x Chiffre les fichiers lors de l'écriture. Une clé de chiffrement sera demandée. Peut ne pas être disponibles dans certains pays.

    -X Ne se connecte pas au serveur X. Accélère le temps de démarrage dans un terminal, mais le titre de la fenêtre et le presse-papier seront inaccessibles.

    -y Démarre Vim en mode Débutant (easy), comme si l'exécutable s'appelait "evim" ou "eview". Donne à Vim un comportement plus proche des éditeurs « cliquez-tapez ». Mais en toute logique, cette option ne peut être utilisée qu'en mode graphique, car il faut un menu pour sauver/quitter (si on peut peut pas le faire en mode commande.

    -Z Mode restreint. Fonctionne comme si l'exécutable commençait par la lettre 'r'.

    -- Délimite la fin des options. Les arguments qui suivent seront considérés comme des noms de fichiers. Cela permet d'éditer des fichier débutant par un '-'.

    MODES DE 'vi'

    Il existe trois modes principaux dans 'vi' :

    On peut considérer qu'il y a deux parties d'écran, la page de texte et la dernière ligne de l'écran.

    Pleine page ::= Mode normal et initial. Certaines commandes retournent en mode commande après exécution. La touche <ESC> (escape ou Echappement) est utilisée pour annuler une commande partielle.

    Dans une pleine page de texte, toutes les saisies de caractères sont interprétés comme des commandes pleine page.

    Lorsque que l'on saisit un ou plusieurs caractères de commande pleine page, il n'y a pas besoin de validation, vi interprète ces caractères à la volée.

    Les caractères suivant font passer dans un autre mode :



    La plupart une fois la recherche ou la commande exécutée, 'vi' repasse en mode pleine page.


    Saisie ::= On entre dans le mode 'saisie' en composant une des lettres <A>, <a>, <c>, <C>, <i>, <I>, <o>, <O>, <R>, <s>, <S>. N'importe quel texte peut alors être composé et l'on sort du mode saisie :


    Ligne de commande ::= Saisie d'une commande en dernière ligne appelée par un des caractères suivants : [:/?!] (:, /, ou ? ) . La saisie d'une commande ou d'un motif de recherche est validée par <CR> ou annulée par <CTRL>+C .


    EXEMPLE DE COMMANDES PLEINE PAGE
    Dans la suite des ces descriptions <CR> sera utilisé pour la touche de validation et <ESC> pour la touche 'ESCAPE' (Echappement) .

    COMMANDE SIMPLES :
       ┌────────────────────────┬──────────────────────────────────────────────┐
       │ j ::= Flèche en bas    │ Déplacement en bas d'une ligne.              │
       │ k ::= Flèche en haut   │ Déplacement en haut d'une ligne.             │
       │ h ::= Flèche à gauche  │ Déplacement à gauche d'un caractère.         │
       │ l ::= Flèche à droite  │ Déplacement à droite d'un caractère.         │
       │ i     (Ex:iabcd<ESC>)  │ Insertion du texte 'abcd'.                   │
       │ cw    (Ex:cwnew<ESC>)  │ Changement du mot courant par la valeur      │
       │                        │   spécifiée 'new'.                           │
       │ e                      │ Se positionner en fin de mot                 │
       │ a                      │ Ajouter des caractères après le curseur      │
       │ ea    (Ex:eas<ESC>)    │ Ajouter en fin de mot le ou les caractères   │
       │                        │   désirés (Ex.:Mettre le mot au pluriel par  │
       │                        │   ajout d'un 's').                           │
       │ x    nx                │ Suppression caractère ou n caractères        │
       │ u    nu                │ Annulation de la dernière modification       │
       │                        │   ou des n dernières modifications.          │
       │                        │   on peut remonter dans le temps dans        │
       │                        │   la limite de l'historique.                 │
       │ dw   ndw               │ Suppression d'un mot ou n mots.              │
       │ dd   ndd               │ Suppression d'une ligne ou n lignes          │
       │ u                      │ Suppression dernière modification.           │
       │ :wq                    │ Sortie de 'vi' avec mise à jour.             │
       │ ZZ                     │ Sortie de 'vi' avec mise à jour.             │
       │ :q!<CR>                │ Sortie sans mise à jour.                     │
       │ /texte<CR>             │ Recherche de la sous-chaîne 'texte' ou       │
       │                        │   de l'expression régulière spécifiée.       │
       │ :cde<CR>               │ Appel de commandes de 'ed' ou 'ex'.          │
       └────────────────────────┴──────────────────────────────────────────────┘
    

    VALEURS NUMERIQUES DEVANT DES COMMANDES DE 'vi'. Certaines commandes peuvent être précédées d'une valeur numérique qui indiquera le nombre de fois que la commande devra être exécutée.

    Pour les commandes de positionnement il s'agira de la valeur où l'on désire se positionner (z, G ^U ou ^D).

    INTERRUPTION ANNULATION
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ INTERRUPTION / ANNULATION                                               │
     ├───────────┬─────────────────────────────────────────────────────────────┤
     │    ESC    │  Fin d'insertion ou commande incomplète                     │
     │    DEL    │  ('delete' ou 'rubout') interruption de la commande         │
     │    ^L     │  Rafraîchissement de l'écran                                │
     │    ^R     │  Si la touche ^L correspond à une autre valeur (<-)         │
     └───────────┴─────────────────────────────────────────────────────────────┘
    

    MANIPULATION DE FICHIERS
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ MANIPULATION DE FICHIERS                                                │
     ├────────────┬────────────────────────────────────────────────────────────┤
     │ ZZ         │ Sortie avec, s'il y a eu des modifications, écriture du    │
     │            │ fichier                                                    │
     │ :wCR       │ Ecriture des modifications sans sortie de 'vi'             │
     │ :w!CR      │ Forçage du droit d'écriture si possible                    │
     │ :qCR       │ Sortie                                                     │
     │ :q!CR      │ Sortie sans écriture des modifications                     │
     │ :e nomCR   │ Edition du fichier spécifié                                │
     │ :e!CR      │ Annulation des modifications de la session                 │
     │ :e + nomCR │ Edition du fichier spécifié mais pos. en fin de fichier    │
     │ :e +nCR    │ Edition avec positionnement à la nième ligne               │
     │ :e #CR     │ Alternance fichier_x / fichier_y                           │
     │ :e! #CR    │ Alternance fichierx/fichiery avec annulation modification  │
     │ :w nomCR   │ Ecriture dans le fichier spécifié                          │
     │ :w! nomCR  │ Ecriture avec remplacement dans le fichier spécifié        │
     │ :shCR      │ Appel d'un sous-SHELL et retour à 'vi' en fin de SHELL     │
     │ :!cdeCR    │ Appel d'une cde SHELL et retour à 'vi' après exécution     │
     │ :nCR       │ Passage au fichier suivant (dans la liste des arguments)   │
     │ :n argsCR  │ Définition d'une nouvelle liste d'arguments                │
     │ ^G         │ Affichage informations sur le fichier et la ligne courants │
     │ :ta tagCR  │ Positionnement curseur sur l'étiquette 'tag'               │
     └────────────┴────────────────────────────────────────────────────────────┘
    

    En général toutes les commandes de 'ex' ou 'ed' (ex: substitute ou global) peuvent être saisies précédées d'un ':' et validées par un 'CR'.

    POSITIONNEMENT DANS UN FICHIER
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ POSITIONNEMENT DANS UN FICHIER                                          │
     ├───────────┬─────────────────────────────────────────────────────────────┤
     │  nG       │ Positionnement en début de la nième ligne. Si 'n' n'est pas │
     │           │   pas spécifié alors positionnement sur la dernière ligne.  │
     │           │   1G ::= Positionnement en début de fichier.                │
     │           │   G  ::= Positionement en fin de fichier.                   │
     │  ^F       │ Page avant ('Forward')                                      │
     │  ^B       │ Page arrière ('Backward')                                   │
     │  ^D       │ Rotation avant d'un demi écran                              │
     │  ^U       │ Rotation arrière d'un demi écran                            │
     │  /motif   │ Prochaine ligne contenant le texte spécifié ou              │
     │           │   correspondant à l'Expression Régulière spécifiée          │
     │  ?motif   │ Ligne précédente contenant le texte spécifié ou             │
     │           │   correspondant à l'Expression Régulière spécifiée          │
     │  n        │ Répétition dernière commande / ou ?                         │
     │  N        │ Répétition avec inversion de sens de la dernière cde / ou ? │
     │  /pat/+n  │ Nième ligne suivant la ligne contenant le texte spécifié    │
     │           │   ou correspondant à l'Expression Régulière spécifiée       │
     │  ?pat?-n  │ Nième ligne précédant la ligne contenant le texte spécifié  │
     │           │   ou correspondant à l'Expression Régulière spécifiée       │
     │  ]]       │ Fonction/Chapitre suivant                                   │
     │  [[       │ Fonction/Chapitre précédent                                 │
     │  (        │ Début de phrase courante                                    │
     │  )        │ Fin de phrase courante                                      │
     │  {        │ Début de paragraphe                                         │
     │  }        │ Fin de paragraphe                                           │
     │  %        │ Recherche du caractère ( ) ou { } correspondant à celui     │
     │           │   sur lequel se trouve le curseur.                          │
     │           | Si le curseur se trouve sur une '{' on cherche la '}'       │
     │           |   correspondante.                                           │
     │           | Si le curseur se trouve sur une ')' on cherche la '('       │
     │           |   correspondante.                                           │
     │           │ Ces recherches se font en respectant les imbrications de    │
     │           │   niveau.                                                   │
     └───────────┴─────────────────────────────────────────────────────────────┘
    

    CONTROLE ECRAN
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ CONTROLE ECRAN                                                          │
     ├───────────────┬─────────────────────────────────────────────────────────┤
     │  ^L           │ Effaçage écran et ré-affichage du contenu               │
     │  ^R           │ Effaçage écran et ré-affichage du contenu si            │
     │               │   '^L=touche <-'                                        │
     │  zCR          │ Ré-affichage avec ligne courante en début d'écran       │
     │  z-CR         │ Ré-affichage avec ligne courante en bas d'écran         │
     │  z.CR         │ Ré-affichage avec ligne courante en milieu d'écran      │
     │  /texte/zCR   │ Recherche expression régulière et affichage page écran  │
     │  /texte/z.CR  │   avec la ligne trouvée en fonction 'z', 'z.' ou 'z-'   │
     │  /texte/z-CR  │   spécifiée.                                            │
     │  zn.CR        │ Affichage d'une fenêtre de n lignes                     │
     │  ^E           │ Rotation vers le bas d'une ligne                        │
     │  ^Y           │ Rotation vers le haut d'une ligne                       │
     └───────────────┴─────────────────────────────────────────────────────────┘
    

    MARQUAGE ET RETOUR
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ MARQUAGE ET RETOUR                                                      │
     ├─────────┬───────────────────────────────────────────────────────────────┤
     │  ``     │  Repositionnement curseur à la position précédente ou         │
     │         │    au contexte précédent.                                     │
     │  ''     │  Pos. premier caractère différent de l'espace dans la ligne.  │
     │  mx     │  Marquage position avec la lettre spécifiée                   │
     │  `x     │  Positionnement à la position marquée 'x'                     │
     │  'x     │  Positionnement premier caractère non espace dans la ligne    │
     │         │    marquée 'x'.                                               │
     └─────────┴───────────────────────────────────────────────────────────────┘
    

    POSITIONNEMENT LIGNE
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ POSITIONNEMENT LIGNE                                                    │
     ├─────────────────────┬───────────────────────────────────────────────────┤
     │ H                   │ Retour première ligne écran (Home)                │
     │ L                   │ Positionnement dernière ligne écran (Last)        │
     │ M                   │ Positionnement milieu d'écran (Midle)             │
     │ +                   │ Premier caractère ligne suivante                  │
     │ -                   │ Premier caractère ligne précédante                │
     │ CR                  │ 'Return' identique à '+'                          │
     │ j ou flèche en bas  │ Ligne suivante dans la même colonne               │
     │ k ou flèche en haut │ Ligne précédente dans la même colonne             │
     └─────────────────────┴───────────────────────────────────────────────────┘
    

    POSITIONNEMENT DANS UNE LIGNE
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ POSITIONNEMENT DANS UNE LIGNE                                           │
     ├───────────┬─────────────────────────────────────────────────────────────┤
     │  ^        │ Premier caractère différent d'un espace                     │
     │  0        │ Début de ligne                                              │
     │  $        │ Fin de ligne                                                │
     │  l ou flèche à droite   Avance d'un caractère                           │
     │  h ou flèche à gauche   Arrière d'un caractère                          │
     │  Espace   │ Avance d'un caractère (comme l ou flèche à droite)          │
     │  ^H       │ Arrière d'un caractère (comme h ou la flèche à gauche)      │
     │  fx       │ Recherche avant caractère spécifié dans la ligne courante   │
     │  Fx       │ Recherche arrière caractère spécifié dans la ligne courante │
     │  tx       │ Pos. au caractère qui précède le caractère spécifié         │
     │  Tx       │ Pos. au caractère qui suit le caractère spécifié            │
     │  ;        │ Répétition dernière commande f, F, t ou T                   │
     │  ,        │ Répétition avec inversion sens dernière cde f, F, t ou T    │
     │  n│       │ Déplacement en nième colonne                                │
     └───────────┴─────────────────────────────────────────────────────────────┘
    

    GESTION MOTS, PHRASES, PARAGRAPHES
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ GESTION MOTS, PHRASES, PARAGRAPHES                                      │
     ├─────────────────────────────────────────────────────────────────────────┤
     │ mot        ::= Suite de caractères séparés par des espaces, ',', ';',   │
     │                '.', '(' , ')' etc..                                     │
     │ phrase     ::= Suite de mots une fin de phrase est un '.' ou une ligne  │
     │                vide.                                                    │
     │ paragraphe ::= Suite de lignes non vides séparées par une ligne vide    │
     │                en début et en fin de paragraphe.                        │
     ├──────────┬──────────────────────────────────────────────────────────────┤
     │  w       │  Avance en début de mot suivant (word)                       │
     │  b       │  Retour en début de mot précédant (back)                     │
     │  e       │  Aller en fin de mot courant (end)                           │
     │  )       │  Aller en avant en début de phrase suivante                  │
     │  }       │  Aller en avant en début de paragraphe suivant               │
     │  (       │  Retour en arrière début de phrase                           │
     │  {       │  Retour en arrière début de paragraphe                       │
     │  W       │  Avance au mot suivant séparé par un ou plusieurs espaces.   │
     │  B       │  Retour au mot précédant séparé par un ou plusieurs espaces. │
     │  E       │  Positionnement fin de mot suivant séparé par un ou          │
     │          │    plusieurs espaces.                                        │
     └──────────┴──────────────────────────────────────────────────────────────┘
    

    CORRECTIONS DURANT L'INSERTION
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ CORRECTIONS DURANT L'INSERTION                                          │
     ├───────────────┬─────────────────────────────────────────────────────────┤
     │  ^H           │ Suppression du dernier caractère composé                │
     │  ^W           │ Suppression du dernier mot                              │
     │  Touche erase │ Identique à ^H                                          │
     │  Touche kill  │ (^u) Suppression de tout le texte saisi en insertion    │
     │  \            │ Permet de marquer un des caractères 'erase' ou 'kill'   │
     │  ESC          │ Termine l'insertion et revient en mode éditeur.         │
     │  DEL          │ Arrêt et termine le mode insertion                      │
     │  ^D           │ Tabulation arrière (marge automatique)                  │
     │  ^^D          │ Destruction de la marge automatique pas celle de la     │
     │               │   ligne suivante.                                       │
     │  0^D          │ Retour début de ligne avec destruction marge            │
     │               │   automatique                                           │
     │  ^V           │ Insertion d'un caractère non affichable                 │
     └───────────────┴─────────────────────────────────────────────────────────┘
    

    INSERTION ET REMPLACEMENT
     ┌─────────────────────────────────────────────────────────────────────────────────────────┐
     │ INSERTION ET REMPLACEMENT                                                               │
     ├─────────────┬───────────────────────────────────────────────────────────────────────────┤
     │    a        │ Insertion après le curseur(append)                                        │
     │    A        │ Ajout en fin de ligne courante (Append)                                   │
     │    cw       │ Change le mot à partir du curseur                                         │
     │    C        │ Change la ligne à partir du curseur                                       │
     │    i        │ Insertion à partir du curseur                                             │
     │    I        │ Insertion dans la ligne courante à partir du premier caractère non blanc  │
     │    o        │ Insérer une ligne derrière la ligne courante                              │
     │    O        │ Insérer une ligne devant la ligne courante                                │
     │    ~        │ Inverser le caractère courant majuscule/MAJUSCULE                         │
     │    rx       │ Remplacer le caractère courant par le caractère spécifié                  │
     │    R        │ Passage en mode remplacement                                              │
     │             │   avant la saisie de ESC.                                                 │
     └─────────────┴───────────────────────────────────────────────────────────────────────────┘
    

    OPERATEURS
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ OPERATEURS                                                              │
     ├─────────────────────────────────────────────────────────────────────────┤
     │   Les opérateurs sont suivis par une fonction de déplacement de curseur │
     │     et traitent tout le texte qui a été affecté par ce déplacement.     │
     │   Exemple 'w' se déplace en début de mot suivant donc 'dw' supprimera   │
     │     le mot. Les opérateurs doubles (Exemple 'dd' ) traitent des lignes  │
     │     complètes.                                                          │
     ├─────────┬───────────────────────────────────────────────────────────────┤
     │    d    │  Suppression                                                  │
     │    c    │  Remplacement caractère(s) courant(s)                         │
     │    y    │  Mémoriser caractères dans un tampon (voir restitution tampon │
     │         │  avec la lettre 'p' ou 'P')                                   │
     │    <    │  Décalage vers la gauche                                      │
     │    >    │  Décalage vers la droite                                      │
     │    !    │  Filtrage par une commande                                    │
     └─────────┴───────────────────────────────────────────────────────────────┘
    

    OPERATIONS DIVERSES
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ OPERATIONS DIVERSES                                                     │
     ├─────────┬───────────────────────────────────────────────────────────────┤
     │    C    │  Remplacement du reste de la ligne (c$)                       │
     │    D    │  Suppression du reste de la ligne (d$)                        │
     │    s    │  Substitution chaîne (cl)                                     │
     │    S    │  Substitution lignes (cc)                                     │
     │    J    │  Concaténation ligne avec la suivante                         │
     │    x    │  Suppression caractère (dl)                                   │
     │    X    │  Suppression devant le caractère (dh)                         │
     │    Y    │  Mémorisation lignes dans un tampon (yy) (Voir restitution    │
     │         │    tampon avec la lettre 'p' ou 'P').                         │
     └─────────┴───────────────────────────────────────────────────────────────┘
    

    GESTION TAMPON ('PICK/PUT') La gestion des tampons fait l'objet d'un chapitre complet. Il existe dans 'vi' un tampon par défaut, 26 tampons (de 'a' à 'z') chargeables avec 'y' ou 'Y' et 9 tampons (de '1' à '9') chargés automatiquement lors de la suppression d'objet.

    (Voir chapitre 'TAMPONS dans 'vi').

     ┌─────────────────────────────────────────────────────────────────────────┐
     │ GESTION TAMPON (PICK/PUT)                                               │
     ├──────────┬──────────────────────────────────────────────────────────────┤
     │    3yy   │ Mémorisation de 3 lignes                                     │
     │    3yl   │ Mémorisation de 3 caractères                                 │
     │    p     │ Insertion tampon derrière le curseur                         │
     │    P     │ Insertion tampon devant le curseur                           │
     │    "xp   │ Insertion du tampon spécifié par 'x'                         │
     │    "xy   │ Mémorisation dans le tampon nommé 'x'                        │
     │    "xd   │ Suppression dans le tampon 'x'                               │
     └──────────┴──────────────────────────────────────────────────────────────┘
    

    Pour plus de détail voir le chapitre 'TAMPONS DE vi'.

    ANNULATION , RECUPERATION
     ┌─────────────────────────────────────────────────────────────────────────┐
     │ ANNULATION , RECUPERATION                                               │
     ├──────────┬──────────────────────────────────────────────────────────────┤
     │    u     │ Annulation dernière modification.                            │
     │    U     │ Restauration ligne en cours.                                 │
     │    .     │ Répétition dernière modification                             │
     │    "np   │ Restitution de la nième suppression                          │
     └──────────┴──────────────────────────────────────────────────────────────┘
    

    Pour plus de détail voir le chapitre 'TAMPONS DE vi'.




     4.1.1 : TAMPONS DANS 'vi'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    En cas d'erreur sur une commande de modification, il est possible d'annuler le résultat et de revenir à l'état initial avant cette commande en composant 'u'. Mais ceci ne permet pas de remonter dans le temps.

    La commande 'U' permet de restaurer la ligne courante telle quelle était lorsque que l'on s'était positionné dessus. Ceci permet de restaurer cette ligne même si elle a été modifiée en plusieurs fois, ce que la commande 'u' ne permettrait pas.

    Mais la commande 'U' ne peut être utilisée que pour des modifications apportées sur la même ligne. Dès qu'une nouvelle ligne devient la ligne courante (exemple après des suppressions de ligne ou une recherche de caractère), cette nouvelle ligne courante est mémorisée de façon à être restaurée avec la commande 'U'.

    Pour gérer un historique des suppressions et permettre des déplacements de texte ou des restauration après suppression(s) intempestive(s), 'vi' dispose de 36 tampons.

    1 tampon par défaut qui contient soit le dernier objet supprimé soit le dernier objet mémorisé par la commande 'y' ou 'Y'..

    26 tampons dans lesquels on peut mémoriser des objets à la demande avec la commande 'Y' ou 'y' et ses dérivés par type d'objet.

    Ces tampons seront représentés par les lettres de 'a' à 'z'.

    9 tampons contenant les neuf derniers objets supprimés Ces tampons seront représentés par les chiffres de '1' à '9'.

    Lors d'une suppression d'objet (caractère(s), mot(s), ligne(s)), 'vi' dans neuf tampons les objets détruits. Ces neuf tampons sont gérés en rotation et permettent de restaurer leur contenu à l'endroit où se trouve le curseur. Comme il n'y a que neuf tampons, une dixième suppression d'objet entraîne la rotation des tampons et la disparition du contenu de la plus ancienne suppression.

    Exemple : 10x (suppression de 10 caractères consécutifs) mémorise ces dix caractères dans le tampon le plus récent. Composer dix fois de suite le caractère 'x' supprime aussi 10 caractères, mais comme ceci a été réalisé en dix opérations différentes les neuf tampons auront été utilisés et le premier caractère supprimé aura disparu.

    Mémorisation d'objets dans un des tampons de 'vi'. La commande 'Y' permet de mémoriser la ligne courante et la commande 'y' permet de mémoriser des objets dans un des 26 tampons représentés par une lettre de 'a' à 'z'. Si l'on ne spécifie pas de lettre dans la commande 'y', alors la mémorisation se fait dans le tampon par défaut.

         ┌────────┬───────────────────────────────────────────────────────┐
         │ Y      │ Mémorisation ligne courante dans le tampon par défaut │
         │ yy     │ Mémorisation ligne courante dans le tampon par défaut │
         │ "zY    │ Mémorisation ligne courante dans le tampon 'z'.       │
         │ "ayy   │ Mémorisation ligne courante dans le tampon 'a'.       │
         │ "b3yy  │ Mémorisation 3 lignes dans le tampon 'b'.             │
         │ "c3yw  │ Mémorisation 3 mots dans le tampon 'c'.               │
         └────────┴───────────────────────────────────────────────────────┘
    

    Restauration de tampons de 'vi' La commande 'p' ou 'P' permet de restaurer derrière ou devant le curseur le contenu du tampon spécifié. Si l'on ne spécifie pas de tampon, alors c'est le contenu du tampon par défaut qui sera pris en compte.

    Dans les exemples qui suivent on utilisera la lettre 'p', mais si l'on désire faire une restauration de tampon devant le curseur, on utilisera la lettre 'P'.

         ┌────────┬───────────────────────────────────────────────────────┐
         │ p      │ Restauration du contenu du tampon par défaut          │
         │ "ap    │ Restauration du tampon 'a'                            │
         │ "1p    │ Restauration de la dernière suppression d'objet       │
         │ "2p    │ Restauration de l'avant dernière suppression d'objet  │
         │ .....  │  et ainsi de suite jusque le chiffre '9'.             │
         │ "ap    │ Restauration du tampon 'a' (dont le contenu a été     │
         │        │   mémorisé lors d'un '"ay').                          │
         └────────┴───────────────────────────────────────────────────────┘
    




     4.1.2 : EXEMPLES D'UTILISATION DE 'vi'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre n'a pas pour prétention de répéter toutes les commandes de 'vi', mais plutôt de regrouper les commandes qui sont les plus courantes ou démonstratives. Avec ces exemples de base plus une relecture de la liste exhaustive des commandes, vous aurez une idée de la puissance de 'vi'.

    Appel de 'vi' : vi nom_fichier ou vi nom_fichier1 nom_fichier2 .....

    Dans le cas de l'appel de plusieurs fichiers, la commande ':arg' affiche les fichiers mémorisés, le fichier en cours de traitement sera entre '[]'. On passe d'un fichier au suivant avec ':n'. Lorsqu'il y a eu un passage d'un fichier à un autre on peut passer de celui en cours au précédent en composant ':e#', mais cette commande correspond à une alternance 'fic_x/fic_y' et permet de passer d'une fichier à l'autre sans remonter la liste des fichiers mémorisés. Pour revenir au premier fichier de la liste, composer ':rew'. Pour se positionner directement sur le fichier désiré composer ':e nom_fichier'.

    Pour composer une commande de type 'ex' il faut se positionner en ligne de commande avec un ':' puis valider la commande désirée avec 'CR'. Après exécution le curseur revient à la ligne courante.

    On peut alors répéter la dernière commande 'ex' sans redescendre en ligne de commande, en composant le '.' en mode pleine page.

    A titre d'exemple, les commandes 'ex' équivalentes aux commandes 'vi' sont indiquées dans la première colonne.

      ┌────────────────────────────────────────────────────────────────────────┐
      │ Positionnement                                                         │
      ├──────────────────┬─────────────────────────────────────────────────────┤
      │ :1            1G │ Positionnement en dernière ligne                    │
      │ :10          10G │ Positionnement en dixième ligne                     │
      │ :$            $G │ Positionnement en dernière ligne                    │
      ├──────────────────┴─────────────────────────────────────────────────────┤
      │ Recherche                                                              │
      ├──────────────────┬─────────────────────────────────────────────────────┤
      │ :/toto     /toto │ Recherche vers le bas d'une ligne contenant 'toto'. │
      │ ://        //    │ Répétition de la même recherche vers le bas.        │
      │ :?         ?toto │ Recherche vers le haut d'une ligne contenant 'toto'.│
      │ :??        ??    │ Répétition de la même recherche vers le haut.       │
      │            n     │ Répétition même recherche dans le même sens         │
      │            N     │ Répétition même recherche dans le sens inverse.     │
      │            zCR   │ Affichage ligne courante en haut d'écran.           │
      │            fx    │ Positionnement sur le 'x' de la ligne courante.     │
      │                  │                                                     │
      │            w     │ Avance en début de mot suivant                      │
      │            b     │ Recul en début de mot précédent                     │
      │           3w     │ Avance de trois mots                                │
      │           2b     │ Recul de deux mots                                  │
      ├──────────────────┴─────────────────────────────────────────────────────┤
      │ Suppression                                                            │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │                 │                                                      │
      │          3x     │  Suppression deux caractères                         │
      │ :.,.+1d  2dd    │  Suppression de deux lignes (l.courante+l.suivante)  │
      │          2dw    │  Suppression de deux mots                            │
      │          D      │  Suppression reste de la ligne courante              │
      │          u      │  Annulation dernière modification                    │
      │          U      │  Restauration ligne courante                         │
      ├─────────────────┴──────────────────────────────────────────────────────┤
      │ Coupure ligne / Juxtaposition ligne  (split/join)                      │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │          r+CR   │  Remplacement du caractère courant par 'un 'CR' donc │
      │                 │  suppression de ce caractère et passage du reste de  │
      │                 │  la ligne à la ligne suivante.                       │
      │          J      │  Juxtaposition de la ligne suivante en fin de ligne  │
      │                 │  courante.                                           │
      ├─────────────────┴──────────────────────────────────────────────────────┤
      │ Déplacement de texte                                                   │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │         /coucou/│ Recherche ligne contenant 'coucou'                   │
      │         5dd     │ Suppression de 4 lignes                              │
      │         $G      │ Positionnement en fin de fichier                     │
      │         p       │ Restauration du tampon de suppression                │
      ├─────────────────┴──────────────────────────────────────────────────────┤
      │ Duplication de ligne                                                   │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │        Yp       │ Mémorisation ligne dans le tampon par défaut et      │
      │                 │   insertion du tampon. Donc duplication de ligne.    │
      ├─────────────────┴──────────────────────────────────────────────────────┤
      │ Inversion de caractères                                                │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │        xp       │ Suppression de caractère et réinsertion du caractère │
      │                 │   supprimé derrière le caractère qui suivait.        │
      ├─────────────────┴──────────────────────────────────────────────────────┤
      │ Marquage position de curseur                                           │
      ├─────────────────┬──────────────────────────────────────────────────────┤
      │        ma       │ Mémorisation position curseur avec la lettre 'a'.    │
      │        mb       │ Mémorisation position curseur avec la lettre 'b'.    │
      │        `a       │ Retour en position marquée 'a'.                      │
      │        `b       │ Retour en position marquée 'b'.                      │
      │        'a       │ Retour au premier caractère non espace de la         │
      │                 │   ligne marquée 'a'.                                 │
      │        `ad`b    │ Suppression des lignes comprises entre la ligne      │
      │                 │   marquée 'a' et la ligne marquée 'b'.               │
      │        `a"cy`b  │ Mémorisation des lignes comprise entre la            │
      │                 │   ligne marqué 'a' et la ligne marquée 'b' dans      │
      │                 │   le tampon 'c'.                                     │
      └─────────────────┴──────────────────────────────────────────────────────┘
    




     5 : COMMANDES UTILES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre est consacré aux commandes auxquelles un débutant pourra être confronté.

    Il faut voir les chapitres dédiés à ces commandes comme un résumé de la documentation, mais complétée avec des exemples concrets.

    Pour avoir une liste plus complète voir l'index principal.




     5.1 : chmod  MODIFICATION DE DROITS D'UN FICHIER   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
       ┌──────────────────────────────────────────────┐
       │ chmod ::=  Modification du mode d'un fichier │
       └──────────────────────────────────────────────┘
    

    SYNOPSIS
       ┌────────────────────────────────────────────────────────┐
       │ chmod [ -R ] mode_absolu fichier ...                   │
       │ chmod [ -R ] [ugoa ]{+ │- │=}[ rwxlstugo ] fichier ... │
       └────────────────────────────────────────────────────────┘
    

    DESCRIPTION La commande 'chmod' permet de modifier le 'mode' d'un fichier.

    Le 'mode' d'un fichier spécifie les droits d'utilisation ainsi que d'autres attributs. Le mode pourra être absolu ou symbolique.

    MODE ABSOLU Un mode absolu est spécifié sous forme d'un nombre octal :

            ┌────────────────────────┐
            │ chmod oooo fichier ... │  où chaque 'o' est un chiffre octal
            └────────────────────────┘   de 0 à 7.
    

    Le débutant pourra oublier le premier chiffre octal et se contenter d'utiliser un nombre de trois chiffres.

            ┌────────────────────────┐
            │ chmod ooo fichier ...  │  où chaque 'o' est un chiffre octal
            └────────────────────────┘   de 0 à 7.
    

    Un mode absolu est construit sous forme d'une combinaison par un OU logique des modes suivants :

    4000 --s------ Bit d'Identificateur d'utilisateur d'exécution ('Set user ID', voir chapitre 'BITS SPECIFIQUES').

    2000 -----s--- Bit d'Identificateur de groupe d'exécution ('Set group ID' voir chapitre 'BITS SPECIFIQUES') pour des valeurs de '#' correspondant à un exécutable (7, 5, 3, ou 1).

    1000 --------t Le 'sticky bit' (voir chapitre 'BITS SPECIFIQUES) --------T est positionné à 1.

    Les débutants peuvent commencer ici :

    0400 -r-------- Fichier autorisé en lecture pour le propriétaire.

    0200 --w------- Fichier autorisé en écriture pour le propriétaire.

    0100 ---x------ Fichier autorisé en exécution pour le propriétaire (Pour un répertoire ce bit spécifie la possibilité de traverser ce répertoire pour aller dans ses sous-répertoires).

    0040 ----r----- Fichier autorisé en lecture pour le groupe.

    0020 -----w---- Fichier autorisé en écriture pour le groupe.

    0010 ------x--- Fichier autorisé en exécution pour le groupe (Pour un répertoire ce bit spécifie la possibilité de traverser ce répertoire pour aller dans ses sous-répertoires).

    0004 -------r-- Fichier autorisé en lecture pour les autres.

    0002 --------w- Fichier autorisé en écriture pour les autres.

    0001 ---------x Fichier autorisé en exécution pour les autres (Pour un répertoire ce bit spécifie la possibilité de traverser ce répertoire pour aller dans ses sous-répertoires).

    MODE SYMBOLIQUE Un mode symbolique se spécifie sous le format suivant :

            ┌───────────────────────────────────────────────────────────┐
            │ chmod [ who ]  operateur  [ permission(s) ]   fichier ... │
            └───────────────────────────────────────────────────────────┘
    

    'who' ::= Combinaison des caractères u, g, o, ou a :

    u Droits du propriétaire ('Utilisateur') g Droits de groupe ('Group') o Droits des autres ('Other€s') a Droits de tous ('All')

    Si 'who' est absent alors la valeur par défaut est 'a'.

    'operateur' ::= + , - ou =

    + Ajouter une permission - Enlever la permission = Affectation de façon absolue.

    ATTENTION : '=' travaille en absolu (bien qu'appelé en symbolique) ET il remet les bits non spécifiés à zéro. L'omission de permission avec '=' entraîne une suppression de toutes les permissions.

    permission(s) ::= une combinaison des lettres :

              r         Permission de lecture
              w         Permission d'écriture
              x         Permission d'exécution (ou pour les répertoire permission d'être traversé sans pour autant être lisible afin d'accèder à des sous-répertoires)
              s         Identificateur propriétaire ou groupe d'exécution
              t         Positionnement du 'sticky bit'
              u, g, o   Spécifie que la permission doit être prise dans le
                          mode actuel propriétaire, groupe ou autres.
    
                                  Propr.  Groupe  Autres
                                  rwx     rwx     rwx
    

    Dans cet exemple tous les utilisateurs ont tous les droits.

    On peut spécifier plusieurs modes symboliques séparés par une ',' mais il ne doit pas y avoir d'espace entre chaque mode.

    Les opérations sont exécutées dans l'ordre spécifié.

    Des lettres symboliques multiples suivant un seul opérateur entraînent une exécution simultanée des opérations.

    La lettre 's' n'a de sens qu'avec 'u' ou 'g'.

    La lettre 't' n'a de sens qu'avec 'u'.

    Seul le propriétaire d'un fichier (ou le super utilisateur) peut changer le mode d'un fichier.

    Seul le super utilisateur peut positionner le 'sticky-bit' d'un fichier qui n'est pas un répertoire. Si vous n'êtes pas le super utilisateur il n'y aura pas de modification mais pas de message d'erreur.

    Pour positionner un identificateur de groupe d'exécution il faut que votre groupe corresponde à celui du fichier et que le bit d'exécution de ce fichier soit positionné pour le groupe.

    OPTIONS :

    -R ::= L'option '-R' permet si un des fichiers spécifiés est un répertoire de traiter récursivement le contenu du répertoire et non pas seulement le répertoire.

    EXEMPLES Suppression des droits d'exécution à tous les utilisateurs :

            ┌───────────────────┐
            │ chmod a-x fichier │
            └───────────────────┘
    

    Donner le droit de lecture à tous les utilisateurs :

            ┌───────────────────┐
            │ chmod 444 fichier │
            └───────────────────┘
    

    Rendre accessible un fichier en lecture et écriture au groupe ainsi qu'aux autres utilisateurs.

           ┌─────────────────────┐       ┌───────────────────┐
           │ chmod go+rw fichier │       │ chmod 066 fichier │
           └─────────────────────┘       └───────────────────┘
    

    Provoquer le verrouillage du fichier en cas d'accès :

            ┌──────────────────┐
            │ chmod +l fichier │
            └──────────────────┘
    

    Autorisation de lecture, écriture et exécution et positionnement du bit d'identificateur groupe d'exécution :

            ┌────────────────────────┐  ┌────────────────────┐
            │ chmod =rwx,g+s fichier │  │ chmod 2777 fichier │
            └────────────────────────┘  └────────────────────┘
    

    Un mode absolu d'identificateur de groupe est impossible pour un répertoire.

    Vous devez utiliser g+s ou g-s.

    TABLEAU RECAPITULATIF

    En partant de fichiers 'rw-------' les commande suivantes donneront les résultats suivants :

        ┌──────────────────────────────────────────────────┐
        │   u-w                  400         r--------     │
        │   -w                   400         r--------     │
        │   go+r                 644         rw-r--r--     │
        │   go=r                 644         rw-r--r--     │
        │   go+rw                666         rw-rw-rw-     │
        │   =rw                  666         rw-rw-rw-     │
        │   +rx                  755         rwxr-xr-x     │
        │   =r                   444         r--r--r--     │
        │   ug=rw,o=r            664         rw-rw-r--     │
        │   u=rwx,g=rx,o=        750         rwxr-x---     │
        │   +x,u+s              4711         rws--x--x     │
        │   +xt                 1711         rwx--x--t     │
        │   ug=rwx+s,o=         6770         rwsrws---     │
        │   u=rwx,g=rwx+s,o=    2770         rwxrws---     │
        │   u=rwx+s,g=rwx,o=    4770         rwxrws---     │
        │   u=rw,g=rw+l,o=      2660         rw-rwl---     │
        │   u=rw,g=r+l,o=r      2644         rw-r-lr--     │
        └──────────────────────────────────────────────────┘
    

    VOIR AUSSI
       ┌─────────────────┐
       │ ls, chmod, stat │
       └─────────────────┘
    

    NOTES 'chmod' permet de changer le mode d'un fichier sans s'occuper de son contenu.

    Un mode 'exécutable' pourrait être donné sans problème à un fichier de données.

    DIAGNOSTICS
       ┌────────────────────────────────────────────────────────────────┐
       │ 0 ::= En cas de succès il y aura un code retour égal à 0.      │
       │ 1 ::= Dans le cas contraire il y aura un code retour égal à 1. │
       └────────────────────────────────────────────────────────────────┘
    




     5.1.1 : BITS SPECIFIQUES DE 'chmod'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    En plus des droits d'écriture, lecture et exécution, il existe d'autres paramètres appelés 'BITS SPECIFIQUES'. Ces bits sont positionnés avec des modes absolus '4000', '2000' ou '1000' ou en mode symbolique avec les lettres 's', ou 't'. Lorsqu'ils sont positionnés ils sont affichés en lieu et place des valeurs 'rwx' traditionnelles.

    Set User ID (1er 's bit') Le bit 'Set User ID' est un des deux 's bit' possibles et permet s'il est positionné sur un exécutable, de faire en sorte que lors de son exécution, le programme est considéré comme exécuté par le propriétaire du programme et non pas celui qui lance ce programme.

    La commande 'ls -l' affiche un 's' à la place d'un 'x' dans la première partie (Droit pour le propriétaire). : Exemple '-rws------'

    Set Group ID (2ème 's bit') Le bit 'Set Group ID' est un des deux 's bit' possibles et permet s'il est positionné sur un exécutable, de faire en sorte que lors de son exécution, le programme est considéré comme exécuté par un utilisateur du 'groupe effectif' auquel appartient le programme et non pas celui auquel appartient celui qui lance ce programme. Le 'groupe réel' reste celui de l'utilisateur qui lance le programme.

    La commande 'ls -l' affiche un 's' à la place d'un 'x' dans la deuxième partie (Droit pour le groupe). : Exemple '----r-s---'

    ATTENTION : Le positionnement de tels 'bits' n'est possible que pour des exécutables et non pas des scripts SHELL. Lorsque l'on exécute un script SHELL, l'exécutable est le SHELL '/usr/bin/sh' lui-même et c'est lui qui exécute l'interprétation du script.

    CAS PARTICULIER DES REPERTOIRES : Si l'on positionne un tel bit pour un répertoire, tout fichier créé dans ce répertoire aura comme groupe le groupe du répertoire. Mais il n'y a pas d'équivalent pour le SUID.

    Pour des raisons de sécurité, seul 'root' permet de positionner de tels 'bits'. Et si un fichier est modifié, alors ces 'bits' sont supprimés, toujours pour des raisons de sécurité.

    Exemple d'utilisation :

    La commande '/usr/bin/passwd' a les deux 's bits' positionnés et appartient à 'root' 'sys' :

      ┌───────────────────────────────────────────────────────────────────────┐
      │ ---s--s--x   1 root     sys        29313 Mar 19 22:03 /usr/bin/passwd │
      └───────────────────────────────────────────────────────────────────────┘
    

    Ceci permet à des utilisateurs d'exécuter 'passwd' et d'avoir le droit d'écrire dans '/etc/shadow' bien que ce fichier soit protégé.

    Sticky bit (t bit) Ce bit n'a d'effet que sur les répertoires et sur les exécutables.

    Répertoires : Tout répertoire ayant un 't bit' positionné protège les fichier qu'il contient contre les suppressions, changements de nom, ou créations de liens, sauf si - Le(s) fichier(s) appartiennent bien à l'utilisateur - Le répertoire appartient à l'utilisateur - L'utilisateur à des droits d'écriture sur ce ou ces fichier(s) - L'utilisateur est le 'super-utilisateur'

    Exécutables : Gain de temps lors de l'appel d'un programme qui a déjà été appelé. Selon les systèmes, les exécutables ou une partie de ces exécutables sont conservés en mémoire ou dans la 'swap area'.

    Seul le super-utilisateur peut positionner un 'sticky-bit'.

    La commande 'ls -l' affiche un 't' ou 'un 'T' à la place d'un 'x' dans la troisième partie (Droit pour les autres utilisateurs).

    EXEMPLES :

            ┌────────────┐
            │ -rwxrwxrwt │  ::= Sticky bit positionné et droit d'exécution
            └────────────┘        pour les autres utilisateurs égal à 'x'.
    

            ┌────────────┐
            │ -rwxrwxrwT │  ::= Sticky bit positionné et droit d'exécution
            └────────────┘        pour les autres utilisateurs égal à '-'.
    




     5.2 : crontab  GESTION COMMANDES PERIODIQUES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌────────────────────────────────────────────────────────────┐
        │ crontab ::= Gestion des fichiers 'crontab' contenant les   │
        │               paramètres d'appel de commandes périodiques. │
        └────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌───────────────────────────────┐
        │ crontab [nom_fichier]         │   L'argument 'nom_utilisateur'
        │ crontab -e [nom_utilisateur]  │   n'est utilisable que par le
        │ crontab -r [nom_utilisateur]  │   super-utilisateur s'il désire
        │ crontab -l [nom_utilisateur]  │   maintenir les fichiers d'autres
        └───────────────────────────────┘   utilisateurs.
    

    DESCRIPTION

    La commande 'crontab' est prévue pour créer un fichier 'nom_utilisateur' de type 'crontab' dans le répertoire '/var/spool/cron'.

    Ce fichier sert à définir les commandes à lancer de façon régulière et automatique. Et c'est la procédure '/etc/cron' (qui tourne en permanence en arrière plan) qui sera chargée de l'exécution de ces commandes. La commande '/etc/cron' examine les différents fichiers 'nom_utilisateur' existant dans le répertoire '/var/spool/cron'.

    et en fonction de la périodicité définie dans ces fichiers, déclenche les commandes contenues spécifiées.

    Ces fichiers 'nom_utilisateur' peuvent être maintenus par des éditeurs UNIX mais comme ils doivent respecter une certaine syntaxe il vaut mieux utiliser la commande 'crontab' pour leurs maintenances.

    La commande 'crontab' lit par défaut l'entrée standard pour créer le fichier 'nom_utilisateur' dans le répertoire '/var/spool/cron'.

    Si l'on donne un nom de fichier en argument, ce fichier sert à créer le fichier résultat au lieu des informations saisies sur l'entrée standard.

    Le contenu d'un fichier 'crontab' doit respecter une certaine syntaxe (décrite dans le paragraphe suivant) et les informations saisies sur l'entrée standard ou en provenance d'un fichier spécifié en argument sont syntaxiquement vérifiées. En cas d'erreur des messages d'erreur apparaissent indiquant la cause de l'erreur, mais si une seule ligne est incorrecte il n'y aura pas de (re)création du fichier résultat.

    Par contre si la syntaxe est correcte, il y a création ou remplacement du fichier 'nom_utilisateur' dans '/var/spool/cron'.

    Ceci est important car si l'on part d'un fichier spécifié qui ne contient aucune ligne (ou si sur l'entrée standard on compose 'CTRL+D' sans avoir saisi aucune ligne, alors le fichier 'nom_utilisateur' sera (re)créé mais vide. Donc, si l'on utilise par erreur l'entrée standard (en ayant oublié de spécifier un fichier en argument) ne jamais sortir avec avec 'CTRL+D' mais avec 'CTRL+C' afin d'interrompre la commande et non pas lui demander de créer un fichier vide.

    OPTIONS :

    -e ::= Permet de traiter le contenu du fichier 'nom_utilisateur' avec l'éditeur UNIX défini dans la variable d'environnement EDITOR. Si le fichier n'existe pas déjà, l'éditeur présente une page vide et en sortie d'édition le contenu créé sera syntaxiquement vérifié.

    -l ::= Permet d'afficher le contenu du fichier 'nom_utilisateur' l'utilisateur (en fait ce fichier a pour nom :

    '/var/spool/cron/nom_utilisateur'

    -r ::= Permet de supprimer le fichier 'nom_utilisateur' du répertoire '/var/spool/cron'.

    AUTORISATION D'UTILISATION

    La commande 'crontab' est soumise à autorisation pour l'utilisateur.

    Cette autorisation se paramètre (seulement par le super utilisateur) à l'aide de deux fichiers :

    /etc/cron.allow ou /etc/cron.deny

    Si aucun de ces fichiers n'existe, alors crontab ne peut pas être utilisé par aucun utilisateur (sauf le super utilisateur).

    Si le fichier 'cron.allow' existe, il contient les noms des utilisateurs autorisés. En fait le super utilisateur définit dans le fichier la liste des utilisateurs autorisés à utiliser 'crontab'.

    Si le fichier 'cron.allow' n'existe pas mais que le fichier 'cron.deny' existe, alors son contenu définit les personnes non autorisées. Donc par défaut tout utilisateur n'étant pas défini dans 'cron.deny' est autorisé à utiliser 'crontab'.

    Ces deux fichiers ne peuvent être créés ou maintenus que par le super utilisateur. La liste des noms d'utilisateur est stockée dans ces fichiers à raison d'un nom d'utilisateur par ligne.

    SYNTAXE 'crontab' Le contenu des fichier 'nom_utilisateur' ou les entrées faites dans ces fichiers par 'crontab' doit respecter une certaine syntaxe :

             ┌────────────────────────────────────────────┐
             │  mm hh JJ MM jj nom_commande [arg1] .....  │
             └────────────────────────────────────────────┘
    

    Les cinq premiers champs permettent de définir la périodicité d'exécution de la commande spécifiée dans le sixième champ. Les champs suivants sont optionnels et contiennent si nécessaire les arguments de la commande à exécuter.

    Si une ligne commence par un '#', elle est considérée comme un commentaire et donc non interprétée.

    Chaque ligne doit comporter au moins six champs séparés par un ou plusieurs espaces ou tabulations.

    Les cinq premiers champs définissent la périodicité :

             mm ::=  minute (0-59),
             hh ::=  heure  (0-23),
             JJ ::=  Jour du mois (1-31),
             MM ::=  Mois dans l'année (1-12),
             jj ::=  Et jour de la semaine (De 0 à 6, Dimanche=0)
    

    Chacun de ces cinq champs peut contenir :

    - Un nombre entier dans les limites précisées précédemment.

    - Deux nombres séparés par un '-' spécifiant un intervalle bornes inclues (1-4 ::= 1,2,3,4) - Une liste de nombres séparés par une ',' indiquant que l'on désire spécifier chaque nombre compris dans la liste.

    1,10,20 ::= 1 ou 10 ou 20 - Un '*' qui signifie toutes les valeurs légales.

    Ces cinq champs définissent la condition de lancement de la commande qui est précisée dans le sixième champ. Cette commande sera exécutée, à chaque fois que les conditions spécifiées dans les cinq premiers champs sont remplies. Les conditions sur le 3ème et le 5ème champ sont liées par un 'OU' logique.

    Exemple :

             0 * * * *       ::=  Tous les jours à chaque changement d'heure
                                  (en fait chaque fois que les minutes passent
                                  à 0).
             0 8-12 * * * *  ::=  A chaque heure comprise entre 8 et 12
             0 0 1,15 * *    ::=  Tous les 1er et 15 du mois
             0 0 1,15 * 1    ::=  Tous les 1er et 15 du mois ou chaque lundi
    

    En toute logique si l'on spécifie un numéro dans le cinquième champ (jour de semaine), il faut utiliser un '*' dans le troisième champ (jour) et réciproquement.

    Le sixième champ sera la commande à exécuter avec la périodicité précisée dans les cinq premiers champs.

    Il est à noter que la commande à exécuter ne peut tenir que sur une ligne. En effet la ligne suivante sera interprétée comme étant une définition de périodicité d'une nouvelle commande.

    On pourra sur une ligne de commande définir des passages virtuels à la ligne suivante en utilisant le caractère '%' qui sera interprété par 'cron'.

    Si l'on désire utiliser le caractère '%' en tant que caractère il faudra le marquer avec un '\'.

    Mais la commande envoyée au SHELL sera TOUJOURS la première ligne logique (devant le premier '%') les autres lignes logiques ainsi définies serviront d'entrée standard pour la commande.

    Exemple :

       ┌────────────────────────────────────────────────────────────────────┐
       │ 00 12 * * * cat >/dev/console %===========%IL EST MIDI%=========== │
       └────────────────────────────────────────────────────────────────────┘
    

    Cette définition utilisera la commande 'cat >/dev/console' avec comme entrée standard : =========== IL EST MIDI ===========

       ┌───────────────────────────────────────────────────────────────────────┐
       │ 00 12 * * * for i in 1 2 3 % do echo "MIDI\007" >/dev/console" % done │
       └───────────────────────────────────────────────────────────────────────┘
    

    Cette définition envoie la commande 'for i in 1 2 3' au SHELL et seulement cette 'partie' de commande. Donc le résultat n'est pas syntaxiquement correct pour le SHELL et aboutit à un message d'erreur qui sera retourné via 'mail'.

    Le SHELL sera invoqué à partir de la 'home-directory' avec un 'arg0' de 'sh'. Les utilisateurs souhaitant que leur '.profile' soit exécuté doivent le spécifier dans la commande (Ex.: '. .profile') La commande 'cron' fournit de base : 'HOME', 'LOGNAME', 'SHELL' ('=/bin/sh') et 'PATH=:/bin:/usr/bin:/usr/lbin' .

    ATTENTION : Les utilisateurs doivent re-diriger les sorties standard et d'erreur dans leurs commandes. Si ce n'est pas le cas ces sorties sont redirigées vers l'utilisateur via 'mail'.

    La commande 'cron' examine les fichiers 'crontab' à chaque minute pour voir si son contenu a changé et dans ce cas il lira le nouveau contenu.

    Donc il faut au maximum une minute pour qu'une modification de fichier soit prise en compte.

    DIAGNOSTIC La commande 'crontab' examine syntaxiquement le contenu des lignes en provenance de l'entrée standard ou du fichier spécifié en argument et signale les lignes incorrectes.

    Si une seule ligne est incorrecte, il n'y a pas de création du fichier résultat '/var/spool/cron/nom_utilisateur'

    FICHIERS
      ┌──────────────────────────┐
      │ /var/spool/cron          │  Répertoire des fichiers 'utilisateur'.
      │ /var/log/cron            │  Journal des actions lancées par 'cron'.
      │ /etc/cron.allow          │  Liste des utilisateurs autorisés.
      │ /etc/cron.deny           │  Liste des utilisateurs non autorisés.
      └──────────────────────────┘
    

    VOIR AUSSI
       ┌────────────────────────────────────────────────────────────────────┐
       │ sh(1), cron(1).                                                    │
       └────────────────────────────────────────────────────────────────────┘
    




     5.3 : find RECHERCHE DANS UNE ARBORESCENCE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
       ┌─────────────────────────────────────────────────────────────────────────────────────┐
       │ find ::= Recherche fichiers à partir d'un ou de plusieurs répertoires et dans toute │
       │            l'arborescence des leurs sous-répertoires.                               │
       └─────────────────────────────────────────────────────────────────────────────────────┘
    

    SYNOPSIS
       ┌─────────────────────────────────────────────────────────────────────────┐
       │ find [options] rep1 [ rep2 ... ] [expression]                           │
       │ find [-H] [-L] [-P] [-D opt_debug ] [-Oniveau] [ rep ...] [expression]  │ 
       └─────────────────────────────────────────────────────────────────────────┘
    

    DESCRIPTION

    La commande 'find' permet de descendre de façon récursive à partir d'un ou plusieurs noms de répertoires indiqués dans la liste des noms de path, et d'exécuter des critères de sélection et enfin des commandes d'affichage ou d'exécution de commande SHELL pour les fichiers ainsi sélectionnés.

    Ce traitement récursif se fera par ordre des numéros d'I-node et non pas par ordre alphanumérique. La primitive '-depth' permet de commencer par le niveau de sous-répertoire le plus interne.

    Si l'on désire un tri alphanumérique plutôt qu'une sortie par numéro d'I-node' on pourra utiliser un '| sort ....' (voir sort).

    rep .... ::= Liste de un ou plusieurs répertoires à examiner La spécification des répertoires (en relatif ou absolu) sera essentielle pour la détermination des noms de fichiers fournis par des primitives d'action comme '-print', '-exec', etc...

    En effet le nom du fichier sélectionné par 'find' sera ajouté au nom du répertoire et donnera un chemin relatif ou absolu selon que ce répertoire a été spécifié en relatif ou en absolu.

    expression ::= Liste de primitives de sélection ou d'action Les sélections se définiront à l'aide de primitives qui seront considérées comme des expressions booléennes qu'il sera possible de combiner avec des opérateurs (! ou -o). S'il y a des primitives qui se suivent sans opérateur, elles sont par défaut combinées par un 'ET' logique.

    Certaines primitives sous-entendent une 'action' (-print ::= affichage) et il devra y avoir au moins une primitive d'action mais dans le cas contraire 'find' exécutera -print par défaut.

    Une primitive d'action devrait en toute logique être spécifiée après les primitives de sélection afin de traiter les fichiers vraiment sélectionnés par les primitives précédentes.

    Pour les primitives de sélection décrites ci-dessous l'argument 'n' pourra être un entier décimal avec ou sans signe + ou -.

    Sans signe spécifié, la valeur de comparaison devra être strictement égale à la valeur 'n' spécifiée.

    Avec le signe '+', la valeur de comparaison devra être strictement supérieure à la valeur 'n' spécifiée.

    Avec le signe '-', la valeur de comparaison devra être strictement inférieure à la valeur 'n' spécifiée.

    ATTENTION : Si l'on utilise find / -name xxxxxx“ pour simplement localiser un fichier, se souvenir que la commande locateœ est plus performante pour localiser un ou des fichiers car elle s'appuie sur une base de données mise à jour régulièrement par updatedb.



    OPTIONS

    Les options -H, -L et -P permettent de contrôler le traitement des liens symboliques.

    Les cinq options -H, -L, -D et -O doivent être spécifiées devant le premier nom de répertoire.

    L'option -- permet de bien séparer les options (si l'on doit spécifier un répertoire qui aurait un nom du genre -H).





     5.3.1 : EXPRESSIONS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Une expression de find est constituée d'options, de tests et d'action tous ces éléments sont séparés par des opérateurs (-a, -o , ...). On peut donc parler d'une expression (au même titre d'une expression logique) avec des opérandes (options, de tests et d'actions) et des opérateurs entre chaque opérande.


    Si l'on sépare des opérandes (options, tests, actions) par des espaces, find interprète cette séparation comme un and logique.

    Si aucune option n'est spécifiée ou si la seule action est -prune, find considère qu'il doit exécuter par défaut l'action -print.





     5.3.1.1 : OPERATEURS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil






     5.3.1.2 : OPTIONS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre traite des options d'une expression de find, et il ne faut pas les confondre avec les options de find (-H, -P, -L, ...).

    Toutes les options retournent la valeur true. Sauf -daystart, -follow et -regextype, elles n'ont pas d'effet sur les tests. Les options sont traitées au début d'exécution de find contrairement aux tests qui sont exécutés fichier par fichier.

    Les options -daystart, -follow et -regextype auront un effet sur les tests mais uniquement pour ceux qui apparaissent derrière.

    De toute façon l'endroit le plus logique pour placer les options d'expression est en début d'expression.




     5.3.1.3 : TESTS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Pour les tests nécessitant une valeur numérique n, cette valeur pourra prendre une des formes suivantes n, +n ou -n.

    Exemple :

               -size  1024       Teste une taille égale strictement à 1024.
               -size +1024       Teste une taille supérieure à 1204.
               -size -1024       Teste une taille inférieure à 1204.
    





     5.3.1.4 : ACTIONS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

                  Exemple : 
                  find /tmp/foo /tmp/bar -print -quit 
                  Affichera seulement /tmp/foo.
    





     5.3.2 : NOMS DE FICHIERS INHABITUELS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    De nombreuses actions affichent des données qui sont sous le contrôle d'autres utilisateurs. Les noms de fichiers contenant des caractères non ASCII (ou non UTF8 selon l'OS) pourraient entrainer des perturbation d'affichage.

    Les caractères spéciaux sont traité différemment selon les actions de find.





     5.4 : ls AFFICHAGE CONTENU D'UN REPERTOIRE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    NOM
        ┌─────────────────────────────────────────────┐
        │ ls ::= Affichage du contenu d'un répertoire │
        └─────────────────────────────────────────────┘
    

    SYNOPSIS
        ┌─────────────────────  POSIX   ──────────────────────────────────┐
        │ ls [-CFRacdilqrtu1] [--] [nom_1] [[nom_n]...]                   │
        └─────────────────────────────────────────────────────────────────┘
        ┌─────────────────────   GNU    ──────────────────────────────────┐
        │ ls [-1abcdfgiklmnopqrstuvwxABCDFGHLNQRSUX] [nom_1] [[nom_n]...] │
        └─────────────────────────────────────────────────────────────────┘
    

         OPTIONS LONGUES : 
        [-w cols] [-T cols] [-I motif] [--full-time]
        [--show-control-chars] [--block-size=taille]
        [--format={long,verbose,commas,across,vertical,single-column}]
        [--sort={none,time,size,extension}] [--time={atime,access,use,ctime,status}] 
        [--color[={none,auto,always}]]
    

    DESCRIPTION Pour chaque argument qui est un nom de fichier, 'ls' affichera le nom de ce fichier et si option -l ses caractéristiques.

    Pour chaque argument qui est un répertoire, 'ls' affichera le contenu du répertoire. Sauf si option -d, dans ce cas elle affiche seulement le nom du répertoire.

    Par défaut l'affichage se fait par ordre alphabétique.

    Si aucun argument n'est spécifié, alors 'ls' traite par défaut le répertoire courant.

    Quand plusieurs arguments sont spécifiés alors ils sont d'abord triés et les arguments fichiers sont traités avant les arguments répertoires.

    Il y a trois grands types d'affichage :

    - Par défaut et si le fichier de sortie standard est un 'tty' il s'agit d'un affichage multi-colonnes.

    - Par défaut et si le fichier de sortie standard n'est pas un 'tty' il s'agit d'un affichage mono-colonne.

    - L'option '-1' permet de forcer si la sortie standard est un 'tty' un affichage mono-colonne.

    - Avec les options 'C', '-x' et '-m' la commande 'ls' utilise la variable d'environnement '$COLUMNS' pour déterminer le nombre de positions d'une ligne d'affichage.

    Si cette variable n'est pas positionnée alors 'ls' utilise le 'terminfo' et en absence d'information la valeur est par défaut positionnée à 80.

    OPTIONS : :

    -1, --format=single-column Présenter un fichier par ligne. C'est le comportement par défaut lorsque la sortie standard n'est pas un terminal (un pipeline vers une autre commande par exemple).

    -a, --all Afficher tous les fichiers des répertoires, y compris les fichiers commençant par un « . ».

    -b, --escape Présenter les caractères non-affichables des noms de fichiers en utilisant des séquences alphabétiques ou octales commençant par une contre oblique « \ » comme en C. Cette option est identique à -Q avec la différence que les noms de fichiers ne sont pas encadrés de guillemets.

    -c, --time=ctime, --time=status Trier le contenu des répertoires en fonction des dates de changement des statuts de fichiers, plutôt qu'en fonction de la date de modification. S'il s'agit d'un format long, afficher la date de changement de statut plutôt que la date de modification du fichier.

    -d, --directory Afficher les répertoires avec la même présentation que les fichiers, sans lister leur contenu.

    -f Ne pas trier le contenu des répertoires, l'afficher dans l'ordre où il se présente sur le disque. Active les options -a et -U et désactive -l, --color -s, et -t.

    -g Option sans effet, conservée pour assurer la compatibilité avec Unix.

    -h, --human-readable Ajouter une lettre indiquant l'unité de taille, comme M pour méga-octets. (Nouveauté dans fileutils-4.0).

    -i, --inode Afficher le numéro d'index (i-noeud) de chaque fichier à gauche de son nom. Ce numéro identifie un fichier de manière unique au sein d'un système de fichiers donné.

    -k, --kilobytes Si la taille des fichiers est affichée, la mesurer en kilo-octets.

    -l, --format=long, --format=verbose       En plus du nom, afficher le type du fichier, les permissions d'accès, le nombre de liens physiques, le nom du propriétaire et du groupe, la taille en octets, et l'horodatage (de la dernière modification, sauf si une autre date est réclamée). Pour les fichiers vieux de plus de 6 mois, ou en avance sur la date de plus d'une heure, l'horodatage contient l'année à la place de l'heure.

          Pour chaque répertoire indiqué, les fichiers sont précédés d'une ligne « total nb_blocs », où nb_blocs est l'espace disque utilisé par l'ensemble       des fichiers du répertoire.

          Par défaut, on utilise des blocs de 1024 octets. Si la variable d'environnement POSIXLY_CORRECT est configurée, on utilise des blocs de 512 octets       (sauf si l'option -k est fournie). Le calcul de nb_blocs se fait en comptant séparement chaque lien physique. On peut trouver cela dommage.

          Le premier caractère sera un :

                   -   Pour un fichier régulier (données ou exécutable)
                   d   Si l'entrée est un répertoire
                   l   Si l'entrée est un lien symbolique
                   b   Si le fichier est un fichier spécial de type 'bloc'
                   c   Si le fichier est un fichier spécial de type 'caractère'
                   p   Si l'entrée est un 'fifo' (Pipe nommé)
                   s   Si le fichier une une socket.
    

          Les neuf caractères suivants seront interprétés par groupe de trois.

                   uuugggooo   Utilisateur+Groupe+Autres
                   Pour chaque groupe on trouvera les permissions :
                     r-- : Lecture
                     -w- : Ecriture
                     --x : Exécution (ou, pour un répertoire, droit d'être traversé).
    

          Un fichier apparaissant sous la forme -rwxr-x--- est :

         
          Les autorisations d'accès listées sont similaires aux spécifications de modes, mais la commande ls regroupe plusieurs bits dans le troisième caractère de chaque jeu de permissions.
               s si le bit setuid ou setgid et le bit d'exécution correspondant sont tous deux valides.
              
               S si le bit setuid ou setgid est actif mais le bit d'exécution correspondant n'est pas configuré.
              
               t Si les bits « Sticky » et « Exécution par les autres » sont actifs.
              
               T Si le bit « Sticky » est actif mais pas le bit « Exécution par les autres ».
              
               x Si le bit d'exécution est actif mais aucun de ceux cités ci-dessus.
              
               - Sinon.
    -m, --format=commas Afficher sur chaque ligne autant de fichiers que possible, séparés par des virgules.

    -n, --numeric-uid-gid Afficher les UID et GID numériques plutôt que les noms.

    -o Produire un listing de répertoire sous forme longue mais sans les informations de groupe. C'est équivalent à --format=long --no-group. Cette option sert à assurer la compatibilité avec d'autres versions de ls.

    -p, --file-type, --indicator-style=file-type Ajouter un caractère à chaque nom de fichier pour indiquer son type. Cette option est identique à -F sauf que les exécutables ne sont pas marqués. En fait, la version fileutils-4.0 traite l'option --file- ype comme --classify.

    -q, --hide-control-chars Afficher des points d'interrogation à la place des caractères non-imprimables dans les noms de fichiers. C'est le comportement par défaut.

    -r, --reverse Inverser le tri du contenu des répertoires.

    -s, --size Afficher la taille de chaque fichier, mesurée en bloc de 1 Ko, à gauche du nom. Si la variable d'environnement POSIXLY_CORRECT est configurée, la taille est mesurée en blocs de 512 octets (sauf si l'option -k est fournie).

    -t, --sort=time Trier le contenu des répertoires en fonction de la date et non pas en ordre alphabétique. Les fichiers les plus récents sont présentés en premier.

    -u, --time=atime, --time=access, --time=use Trier le contenu des répertoires en fonction de la date de dernier accès au fichier plutôt que selon la date de modification. Si le format d'affichage est large, c'est la date de dernier accès qui est affichée.

    -v Trier le contenu des répertoires en fonction de la version des fichiers. Ceci prend en compte le fait que les noms de fichiers utilisent fréquemment des indices ou des numéros de version. Les fonctions de tri standards ne fournissent pas en général l'ordre attendu car les comparaisons ont lieu caractère par caractère. Le tri de version gère ce problème, et est particulièrement utile lorsque l'on parcourt des répertoires contenant de nombreux indices ou numéros de version dans les noms de fichier. Par exemple :
                 $ ls -1            $ ls -1v
                 foo.zml-1.gz       foo.zml-1.gz
                 foo.zml-100.gz     foo.zml-12.gz
                 foo.zml-12.gz      foo.zml-25.gz
                 foo.zml-25.gz      foo.zml-100.gz
    

    Remarquez que les parties numériques commençant par des zéros sont considérées comme des décimales :
                 $ ls -1            $ ls -1v
                 abc-1.007.tgz      abc-1.007.tgz
                 abc-1.012b.tgz     abc-1.01a.tgz
                 abc-1.01a.tgz      abc-1.012b.tgz
    

    (Ceci est une nouveauté des fileutils-4.0).

    -w, --width cols Supposer que l'écran dispose de cols colonnes en largeur. La valeur par défaut est réclamée si possible au gestionnaire de terminal. Sinon la variable d'environnement COLUMNS est utilisée si elle est positionnée. Sinon, la valeur par défaut est 80.

    -x, --format=across, --format=horizontal Présenter les fichiers en colonnes, triés horizontalement.

    -A, --almost-all Afficher tous les fichiers du répertoire sauf « . » et « .. ».

    -B, --ignore-backups Ne pas afficher les fichiers se terminant par « ~ », à moins qu'ils ne soient mentionnés sur la ligne de commande.

    -C, --format=vertical Présenter les fichiers en colonnes, triés verticalement.

    -D, --dired       Avec le format long -l, imprimer une ligne supplémentaire après les données principales:
          //DIRED// DEBUT_1 FIN_1 DEBUT_2 FIN_2 ...
         
          Les valeurs DEBUT_n et FIN_n sont des entiers non-signés qui enregistrent la position en octets de chaque noms de fichier dans la sortie. Ceci permet à Emacs de trouver facilement les noms de fichiers, même ceux qui contiennent des caractères inhabituels comme espace ou retour-chariot.
         
          Si les répertoires sont listés de manière récursive -R, une ligne similaire est affichée après chaque sous-répertoires :
          //SUBDIRED// DEBUT_1 FIN_1 ...
    -F, --classify Ajouter un caractère à chaque nom de fichier pour indiquer son type. les fichiers réguliers exécutables sont suivis d'un « * ». Les répertoires sont suivis de « / », les liens symboliques d'un « @ », les FIFOs d'un « | ». Les fichiers réguliers non-exécutables ne sont suivis d'aucun caractère.

    -G, --no-group Ne pas afficher les informations de groupe dans le format large.

    -H, --si Fonctionne comme -h, mais en utilisant les unités du Système International (avec des puissances 1000 et pas de 1024). Ainsi M correspond à 1000000 à la place de 1048576. Ceci est une nouveauté des fileutils-4.0.

    -I, --ignore motif Ne pas afficher les fichiers dont le nom correspond au motif (suivant l'interprétation du shell), à moins qu'ils ne soient explicitement mentionnés sur la ligne de commande. Comme avec le shell, les noms de fichiers commençant par un point « . » ne sont pas supposés correspondre avec un motif commençant par un caractère générique. Pour les root-kits élémentaires : ajoutez une ligne LS_OPTIONS="$LS_OPTIONS -I mes_trucs" dans /etc/profile et compagnie pour cacher vos répertoires.

    -L, --dereference Afficher les informations concernant les fichiers pointés par les liens symboliques et non pas celles concernant les liens eux-mêmes.

    -N, --literal Afficher les noms de fichiers sans modification.

    -Q, --quote-name Encadrer les noms de fichiers avec des guillemets, et citer les caractères non-imprimables par des séquences semblables à celles utilisées en C.

    -R, --recursive Afficher récursivement le contenu des sous-répertoires.

    -S, --sort=size Trier les répertoires en fonction de la taille de fichier et non pas en ordre alphabétique. Les fichiers les plus gros sont affichés en premier.

    -T, --tabsize cols Supposer que les tabulations sont espacées de cols colonnes. La valeur par défaut est 8, mais elles peut être modifiée par la variable d'environnement TABSIZE lorsque la variable POSIXLY_CORRECT n'est pas validée. ls utilise des tabulations pour accélérer l'affichage, mais si cols vaut zéro, aucune tabulation ne sera employée.

    -U, --sort=none Ne pas trier le contenu des répertoires. Les présenter dans l'ordre des fichiers sur le disque. La différence entre -U et -f est que le premier ne modifie pas d'options. Ceci sert surtout lorsqu'on liste de gros répertoires, car le tri sera notablement plus rapide.

    -X, --sort=extension Trier le contenu des répertoires en fonction de l'extension du nom de fichier (les caractères après le dernier « . »). Les fichiers sans extension sont affichés en premier.

    --block-size=nombre Afficher les tailles de fichiers en blocs ayant le nombre indiqué d'octets.

    (Nouveauté de fileutils-4.0).

    --color[=manière] Spécifie comment utiliser les couleurs pour distinguer les types de fichiers.

    Les couleurs sont définie en utilisant la variable d'environnement LS_COLORS. Pour avoir des précisions sur la configuration de cette variable, voir dircolors(1). La manière, si elle est indiquée, peut prendre l'une des valeurs suivantes :
          none Ne pas utiliser de couleurs. C'est le comportement par défaut.
         
          auto N'utiliser de couleurs que si la sortie standard est un terminal.
         
          always Toujours utiliser des couleurs. Indiquer seulement --color sans indiquer de manière est équivalent à --color=always.

    --full-time Afficher les temps de manière complète, sans utiliser les heuristiques habituelles d'abréviation. Le format est celui par défaut de date(1). On ne peut pas le modifier, mais on peut au besoin l'extraire avec cut(1) et de passer le résultat à « date -d ».

    Ceci est surtout utile car l'affichage contient les secondes (les systèmes de fichiers Unix utilisent un horodatage à la seconde la plus proche, aussi vous disposez ici de toutes les informations existantes). Par exemple, cela peut servir à corriger un Makefile qui ne régénère pas correctement les fichiers.


    --time-style Permet de spécifier un format de date :
          --time-style=locale en fonction de la locale LC_TIME       --time-style=iso MM-JJ HH:MM       --time-style=long-iso AAAA-MM-JJ HH:MM       --time-style=full-iso AAAA-MM-JJ HH:MM:SS.microsecondes Décalage en heure par rapport à GMT       --time-style=+format Format désiré sous la même forme qu'avec la commande date.
    --quoting-style=style Utiliser le style indiqué pour présenter les noms de fichiers. Le style peut être :
          literal Afficher les noms tels quels. C'est le comportement par défaut de ls.
         
          shell Protéger les noms avec des apostrophes s'ils contiennent des caractères spéciaux ambigus pour le shell.
         
          shell-always Protéger les noms avec des apostrophes même s'ils n'ont a priori pas besoin de protection.
         
          c Encadrer les noms avec des guillemets, comme des chaînes pour le langage C. C'est équivalent à l'option -Q.
         
          escape Protéger comme le style c en évitant les guillemets. Ceci est équivalent à l'option -b.
         
          Une valeur par défaut peut être indiquée dans la variable d'environnement QUOTING_STYLE (Voir le paragraphe ENVIRONNEMENT plus bas).
    --show-control-chars Afficher les caractère non-graphiques tels quels dans les noms de fichiers. C'est le comportement par défaut, sauf si la sortie standard est un terminal et si le programme invoqué est ls.





    OPTIONS STANDARDS GNU
    --help
    Afficher un message d'aide sur la sortie standard, et se terminer normalement.
    --version
    Afficher un numéro de version sur la sortie standard, et se terminer normalement.
    --
    Terminer la liste des options.




    ENVIRONNEMENT
    La variable d'environnement POSIXLY_CORRECT détermine le choix des unités.

    Si elle n'est pas configurée, alors la variable TABSIZE détermine le nombre de caractères par saut de tabulation. La variable COLUMNS (lorsqu'elle contient un entier décimal) déterminer le nombre de colonnes pour la largeur de sortie (option -C). Les noms de fichiers ne doivent pas être tronqués pour tenir dans une sortie multi-colonnes.

    Les variables LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES et LC_TIME ont leurs significations habituelles.

    La variable TZ indique le fuseau horaire pour les chaînes de caractères représentant des horodatages.

    La variable LS_COLORS est utilisée pour préciser les couleurs utilisées.

    La variable LS_OPTIONS contient les options par défaut.

    La variable QUOTING_STYLE indique le comportement par défaut correspondant à l'option --quoting-style. Par défaut elle prend actuellement la valeur literal, mais les auteurs préviennent que cela peut basculer vers la valeur shell dans des versions à venir.



    Exemple d'affichage par 'ls' :

    'ls -l ' affiche un résultat semblable à celui ci
          ┌─────────────────────────────────────────────────────────────┐
          │total 2048                                                   │  Taille en bloc du répertoire 
          │   -rwxrwxrwx  1 dupont snid9  10876  May 16 9:42 fichier1   │
          │   -rwxrwxrwx  1 dupont snid9  10876  May 16 9:42 fichier2   │
          │   -rwxrwxrwx  1 dupont snid9  10876  May 16 9:42 fichier3   │
          │ .......                                                     │
          └─────────────────────────────────────────────────────────────┘
    

    'ls -l fichier1' affiche un résultat semblable à celui ci :

          ┌─────────────────────────────────────────────────────────────┐
          │   -rwxrwxrwx  1 dupont snid9  10876  May 16 9:42 fichier1   │
          │       │       │   │     │       │         │          │      │
          │       │       │ propr.  │     taille      │       nom fich. │
          │       │       │       groupe              │                 │
          │  type │     nb liens                 dte dern.mod.          │
          │  mode fichier                                               │
          └─────────────────────────────────────────────────────────────┘
    

        ┌───┬───┬───┐
        │ 4 │ 2 │ 1 │
        ├───┼───┼───┤
        │ r │   │   │  Fichier accessible en lecture.
        │---│- -│- -│  Permission de lecture non accordée.
        │   │ w │   │  Fichier accessible en écriture.
        │   │ - │   │  Permission d'écriture non accordée.
        │   │   │ x │  Fichier exécutable (ou pour un répertoire, la possibilité d'être traversé).
        │   │   │   │                                      
        │   │   │ - │  Permission d'exécution non accordée.
        │   │   │   │                                      
        │   │   │ s │  Le bit 'set-user-ID' ou 'set-group-ID' est positionné ainsi que celui d'exécution.
        │   │   │   │    L'utilisateur sera considéré comme cet utilisateur et/ou ce groupe.('s bit')
        │   │   │ S │  Etat non-défini (bit 'set-user-ID' est positionné mais pas
        │   │   │   │    celui d'exécution).
        │   │   │ t │  Le 'sticky-bit' (1000 en octal) est positionné ainsi que
        │   │   │   │    celui d'exécution (Voir chmod(1)).
        │   │   │ T │  Etat non-défini : 'sticky-bit' positionné mais pas celui
        │   │   │   │    d'exécution.
        └───┴───┴───┘
    

    Pour chaque groupe de permissions (trois caractères) on trouvera un des caractères ci-dessus selon les droits définis pour ce fichier.

    EXEMPLES DE MODES
            ┌────────────┐
            │ -rwxr--r-- │
            └────────────┘
    

    Fichier lisible, modifiable et exécutable par son propriétaire et uniquement lisible par les utilisateurs du même groupe et par les autres utilisateurs.

            ┌────────────┐
            │ -rwsr-xr-x │
            └────────────┘
    

    Fichier lisible, modifiable et exécutable par son propriétaire et lisible et exécutable par les utilisateurs du même groupe et par les autres utilisateurs.

    De plus l'exécution par un autre utilisateur se fera avec une substitution d'identité avec le propriétaire pendant l'exécution.

            ┌────────────┐
            │ -rw-rwl--- │
            └────────────┘
    

    Le fichier est lisible et modifiable par le propriétaire et les utilisateurs du groupe.

    De plus le fichier peut être bloqué pendant l'accès.

    FICHIERS
       ┌───────────────────────────────────────────────────────────────────────┐
       │ /etc/passwd                      Utilisé par les options '-l' et '-o' │
       │ /etc/group                       Utilisé par les options '-l' et '-g' │
       │ /usr/share/lib/terminfo/?/*      Utilisé pour déterminer la taille    │
       │                                  d'une ligne d'affichage.             │
       └───────────────────────────────────────────────────────────────────────┘
    

    VOIR AUSSI
       ┌────────────────────┐
       │ chmod(1), find(1). │
       └────────────────────┘
    

    NOTES En environnement fichiers partagés à distance l'option '-l' peut ne pas donner les résultats attendus (Voir le 'System Administrator's Guide').

    Les noms de fichier contenant des caractères non ASCII peuvent perturber l'affichage et/ou l'écran. Voir option '-q' ou '-b'.

    Le nombre de blocs total peut être incorrect s'il y des liens en dur entre fichiers.

    EXEMPLES

    ls -lap | grep / ::= Affichage des sous-répertoires contenus dans le répertoire courant, sans afficher leur contenu. L'option 'a' permet aussi de traiter les répertoires commençant par un '.'.

    ls .* ::= Affichage de tous les fichiers commençant par un '.'. Mais dans ce cas le répertoire '..' est traité comme argument et donc son contenu sera affiché, ce qui n'est peut être pas nécessaire.

    ls -d .* ::= Affichage des tous les fichiers commençant par un '.' sans balayer le contenu des répertoires donc en évitant le contenu du '..'.

    ls -lart ::= Affichage des fichiers par ordre croissant de date de dernière modification.




     5.4.1 : EXEMPLES D'UTILISATION DE 'ls'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La variété des options de 'ls' fait qu'il est très difficile de les présenter toutes dans des exemples concrets.

    Ce chapitre a pour objet de présenter les plus courantes.

    De plus comme 'ls' est certainement une des premières commandes que l'on utilise en débutant, il y aura quelques exemples sur ce que fait vraiment la commande et ce qu'à fait le SHELL avant d'exécuter la commande.

    Prenons un utilisateur 'dupond' qui est positionné dans son 'home_directory' : '/home/dupond'.

    Ce répertoire comporte différents sous-répertoires :

    'bin' ::= Pour les exécutables propres à cet utilisateur 'sce' ::= Pour les sources propres à cet utilisateur 'data' ::= Pour les fichiers de données propres à cet utilisateur.

    Il contient aussi :

    '.profile' ::= Script SHELL exécuté en début de session.

      ┌────┐           ┌───────────────────────┐
      │ ls │  Affiche  │ bin      data     sce │
      └────┘           └───────────────────────┘
    

      ┌───────┐           ┌─────────────────────────────────────────────────┐
      │ ls -a │  Affiche  │ .        ..       .profile  bin     data    sce │
      └───────┘           └─────────────────────────────────────────────────┘
    

    L'option '-a' affiche les fichiers commençant par un '.'

      ┌──────┐            ┌────────────────────────┐
      │ ls * │  Affiche   │ bin:                   │
      └──────┘            │ ycat70   ytestsi       │
                          │                        │
                          │ data:                  │
                          │ clients    articles    │
                          │                        │
                          │ sce:                   │
                          │ ycat70.c   ytestsi.c   │
                          └────────────────────────┘
    

    Dans ce cas l'argument '*' a été substitué, par le SHELL, en liste de tous les fichiers ne commençant par par un '.', et ceci à abouti à
        l'exécution de : ┌─────────────────┐
                         │ ls bin data sce │
                         └─────────────────┘
    

    Dans ce cas 'bin', 'data' et 'sce' étant des répertoires, la commande 'ls' affiche le contenu de ces répertoires.

    L'affichage du contenu d'un répertoire ne se fait que pour le premier niveau. Si l'on désire balayer de façon récursive tous les niveaux il faut : Utiliser l'option '-R' de 'ls' Voir la commande 'find'.

    Si l'on ne voulait pas afficher le contenu des répertoires traités par 'ls' il faudrait utiliser l'option '-d'.

      ┌─────────┐           ┌───────────────────────┐
      │ ls -d * │  Affiche  │ bin      data     sce │
      └─────────┘           └───────────────────────┘
    

     ┌─────────┐           ┌───────────────────────────────────────────┐
     │ ls -a * │  Affiche  │ bin:                                      │
     └─────────┘           │ .        ..        ycat70   ytestsi       │
                           │                                           │
                           │ data:                                     │
                           │ .        ..        clients  articles      │
                           │                                           │
                           │ sce:                                      │
                           │ .        ..        ycat70.c   ytestsi.c   │
                           └───────────────────────────────────────────┘
    

    La substitution par le SHELL de '*' a donné le même résultat que précédemment et l'option '-a' a pour effet d'afficher les fichiers cachés dans les répertoires demandés, c'est à dire 'bin', 'data' et 'sce'. Les fichiers commençant par un '.' dans le répertoire courant ne sont pas traités car la substitution du '*' ne le prévoit pas.

     ┌───────┐
     │ ls .* │  Affiche   ┌────────────────────────────┐
     └───────┘            │ .profile                   │
                          │                            │
                          │ .:                         │
                          │ bin     data    sce        │
                          │                            │
                          │ ..:                        │
                          │ dupond  durand  lost+found │
                          └────────────────────────────┘
    

    Dans ce cas la substitution par le SHELL du '.*' a donné :

            ┌──────────────────┐
            │ ls . .. .profile │  Et comme 'ls' traite les fichiers avant les
            └──────────────────┘    répertoires on obtient l'affichage de
    

    '.profile' avant le contenu de '.' et de '..'.

     ┌────────┐           ┌─────────────────────┐
     │ ls bin │  Affiche  │ ycat70      ytestsi │
     └────────┘           └─────────────────────┘
    

     ┌──────────┐            ┌───────────────────────────┐
     │ ls bin/* │  Affiche   │ bin/ycat70    bin/ytestsi │
     └──────────┘            └───────────────────────────┘
    

    La différence n'est pas due à 'ls' mais une fois de plus au SHELL.

    Dans le deuxième cas 'bin/*' a été interprété par le SHELL et 'ls' a reçu comme arguments 'bin/ycat70' et 'bin/ytestsi'.

    Les exemples suivants ne traiteront plus des fonctionnalités du SHELL mais de celles de 'ls'.

    Pour plus de détails sur ces substitutions du SHELL, voir le chapitre 'ETAPES EXECUTION COMMANDE'.

    AFFICHAGE LONG
     ┌────────┐           ┌───────────────────────────────────────────────────┐
     │ ls -la │  Affiche  │total 24                                           │
     └────────┘           │drwxr-xr-x   5 pm   essai 512 Oct  5 15:59 .       │
                          │drwxrwxr-x  12 root sys   512 Oct  5 11:21 ..      │
                          │-rw-r--r--   1 pm   essai  13 Sep 27 13:40 .profile│
                          │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 bin     │
                          │drwxr-xr-x   2 pm   essai 512 Oct  5 15:59 data    │
                          │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 sce     │
                          └───────────────────────────────────────────────────┘
    

     ┌─────────┐           ┌──────────────────────────────────────────────────┐
     │ ls -l * │  Affiche  │bin:                                              │
     └─────────┘           │total 24                                          │
                           │-rwxr-x--- 1 pm  essai 4395 Oct  5 16:08 ycat70   │
                           │-rwxr-x--- 1 pm  essai 4224 Oct  5 16:13 ytestsi  │
                           │                                                  │
                           │data:                                             │
                           │total 8                                           │
                           │-rw-rw-r-- 1 pm  essai 1233 Oct  5 16:04 clients  │
                           │-rw-rw-r-- 1 pm  essai 1544 Oct  5 16:12 articles │
                           │                                                  │
                           │sce:                                              │
                           │total 8                                           │
                           │-rw-rw-r-- 1 pm  essai 1898 Oct  5 16:04 ycat70.c │
                           │-rw-rw-r-- 1 pm  essai 1025 Oct  5 16:12 ytestsi.c│
                           └──────────────────────────────────────────────────┘
    

     ┌──────────┐          ┌───────────────────────────────────────────────────┐
     │ ls -ld * │          │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 bin     │
     └──────────┘          │drwxr-xr-x   2 pm   essai 512 Oct  5 15:59 data    │
                           │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 sce     │
                           └───────────────────────────────────────────────────┘
    

    L'option '-d' demande à 'ls' de ne pas afficher le contenu des répertoires mais seulement leurs caractéristiques.

    Si l'utilisateur a créé d'autres fichiers dans son 'home-directory', on peut toujours utiliser 'ls -ld *' pour n'afficher que ce niveau de répertoire.

     ┌──────────┐          ┌───────────────────────────────────────────────────┐
     │ ls -ld * │          │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 bin     │
     └──────────┘          │drwxr-xr-x   2 pm   essai 512 Oct  5 15:59 data    │
                           │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 sce     │
                           │-rwxr-xr-x   2 pm   essai  92 Oct  5 16:15 toto    │
                           │-rwxr-xr-x   2 pm   essai 102 Oct  5 16:16 titi    │
                           │-rwxr-xr-x   2 pm   essai 250 Oct  5 16:17 tutu    │
                           └───────────────────────────────────────────────────┘
    

    AFFICHAGE LONG + SELECTION

    Si l'on désire ne retrouver que les répertoires :

     ┌─────────────────┐  ┌───────────────────────────────────────────────────┐
     │ ls -lp | grep / │  │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 bin/    │
     └─────────────────┘  │drwxr-xr-x   2 pm   essai 512 Oct  5 15:59 data/   │
                          │drwxr-xr-x   2 pm   essai 512 Oct  5 16:13 sce/    │
                          └───────────────────────────────────────────────────┘
    

    L'option '-p' ajoute un '/' en fin de nom et l'on utilise 'grep /' pour n'afficher que les noms comportant un '/'.

    Si l'on désire afficher tous les fichiers sauf les répertoires :

     ┌────────────────────┐ ┌──────────────────────────────────────────────────┐
     │ ls -lp | grep -v / │ │-rwxr-xr-x   2 pm   essai 102 Oct 5 16:16 titi    │
     └────────────────────┘ │-rwxr-xr-x   2 pm   essai 250 Oct 5 16:17 tutu    │
                            └──────────────────────────────────────────────────┘
    

    Pour plus de précisions sur 'grep' voir la commande 'grep' et la notion d'expression régulière.

    Si dans le répertoire 'bin' il existe d'autres fichiers que des exécutables, alors un 'ls -l' permet déjà de visualiser le 'mode x' de chaque fichier.

     ┌───────────┐          ┌─────────────────────────────────────────────────┐
     │ ls -l bin │          │-rwxr-x--- 1 pm  essai 4395 Oct  5 16:08 ycat70  │
     └───────────┘          │-rwxr-x--- 1 pm  essai 4224 Oct  5 16:13 ytestsi │
                            │-rw-rw---- 1 pm  essai  541 Oct  5 16:18 essai   │
                            └─────────────────────────────────────────────────┘
    

    On pourra faire des sélections sur le mode en utilisant l'option '-F'.

     ┌───────────────────────┐ ┌───────────────────────────────────────────────┐
     │ ls -lF bin | grep '*' │ │-rwxr-x--- 1 pm essai 4395 Oct 5 16:08 ycat70* │
     └───────────────────────┘ │-rwxr-x--- 1 pm essai 4224 Oct 5 16:13 ytestsi*│
                               └───────────────────────────────────────────────┘
    

    L'option 'F' ajoute un '*' en fin de fichier lorsque ceux-ci sont exécutables. On recherche ce '*' par un 'grep'.

     ┌──────────────────────────┐ ┌────────────────────────────────────────────┐
     │ ls -lF bin | grep -v '*' │ │-rw-rw---- 1 pm essai  541 Oct 5 16:18 essai│
     └──────────────────────────┘ └────────────────────────────────────────────┘
    

    L'option '-F' ajoute aussi des '/' pour des répertoires.

    des '@' pour des liens symboliques On peut donc varier les exemples de recherches.

    ATTENTION : Ces recherches ne peuvent être fiables que s'il n'y a pas de fichier dont le nom se termine par le caractère de recherche.

    CHANGEMENT D'ORDRE D'AFFICHAGE

      ┌─────────┐
      │ ls -lar │  ::=  Affiche tous les fichiers mais dans l'ordre inverse
      └─────────┘         de l'ordre alphabétique car l'option '-r' inverse
    

    l'ordre qui est par défaut l'ordre alphabétique.

      ┌─────────┐
      │ ls -lat │  ::=  Affiche par ordre décroissant de date de dernière
      └─────────┘         modification.  Les fichiers les plus récemment
    

    touchés apparaîtront en début de liste.

      ┌──────────┐
      │ ls -lart │ ::= Affiche dans l'ordre inverse de la commande précédente.
      └──────────┘     Les fichiers les moins récemment touchés apparaîtront
    

    en début de liste.

      ┌────────┐
      │ ls -lu │   ::= Affiche la date de dernier accès au lieu de la date
      └────────┘         de dernière modification.
    

      ┌─────────┐
      │ ls -lut │  ::= Trie sur la date de dernier accès au lieu de la date
      └─────────┘        de dernière modification.  Les fichiers les plus
    

    récemment accédés seront en début de liste.

      ┌──────────┐
      │ ls -lurt │ ::= Affiche dans l'ordre inverse de la commande précédente.
      └──────────┘     Les fichiers les moins récemment accédés apparaîtront
    

    en début de liste.

      ┌────────┐
      │ ls -lc │   ::= Affiche la date de dernière modification d'I-node
      └────────┘         (modification des caractéristiques du fichier) au lieu
    

    de la date de dernière modification.

      ┌─────────┐
      │ ls -lct │  ::= Trie sur la date de dernière modification d'I-node.
      └─────────┘      Les fichiers dont l'I-node a été modifié le plus
    

    récemment sont en début de liste.

      ┌──────────┐
      │ ls -lcrt │ ::= Affiche dans l'ordre inverse de la commande précédente.
      └──────────┘     Les fichiers dont l'I-node a été modifié le moins
    

    récemment sont en début de liste.

    AFFICHAGE LONG + TRI

    Pour d'autre tris, il faut utiliser la commande sort :

      ┌─────────────────────┐
      │ ls -l | sort -bnk5  │  Utilise l'affichage long de ls pour l'envoyer à la commande sort avec comme option de trier de  
      └─────────────────────┘    façon numérique et croissante sur le champ 5 en supprimant les espaces surnuméraires.
    

      ┌──────────────────────┐
      │ ls -l | sort -brnk5  │  Même chose que précédemment, mais avec un tri par ordre décroissant.
      └──────────────────────┘    
    

    TRAITEMENT NOMS INDESIRABLES

     ┌────────┐
     │ >-toto │  Crée un fichier '-toto'
     └────────┘
    

     ┌─────────────┐                       ┌─────────────┐
     │ ls -l -toto │ sera intérprété comme │ ls -l -t -o │  et sera donc
     └─────────────┘                       └─────────────┘
    

    considéré comme un appel de 'ls' avec les options '-t' et '-o' sans argument, donc affichera en format long (-l) le contenu du répertoire courant avec tri sur la date de dernière modification (-t) et sans le groupe (-o).

    Si l'on désire obtenir un traitement correct du nom '-toto', il faudra utiliser '--' qui permet de séparer les options des arguments.

     ┌────────────────┐  ┌────────────────────────────────────────────────┐
     │ ls -l -- -toto │  │ -rw-rw---- 1 dupond essai 0 Oct  6 15:17 -toto │
     └────────────────┘  └────────────────────────────────────────────────┘
    

    Dans certains cas l'utilisation de 'soft-keys', 'hard-keys' ou touches de déplacement de curseur entraîne des noms de fichiers incorrects.

    Exemple : Un utilisateur veut créer un fichier 'toto' avec la commande '>toto' mais en composant le nom désiré il utilise des touches de déplacement de curseur avant la validation.

    Dans ce cas comme UNIX n'a pas de contrainte pour les caractères composant un nom de fichier, on peut obtenir dans un répertoire des noms qui ne sont pas composés de caractères alphanumériques. Et dans certains cas les caractères utilisés par ces touches de fonction sont des séquences 'ESC' qui peuvent entraîner un affichage incorrect, (dans certains cas on voit s'afficher le même nom plusieurs fois) ou même perturber complètement l'écran.

      ┌───────┐    ┌──────────────────────────────────────────────────────┐
      │ ls t* │    │-rw-r--r--   1 pm     essai     128 Oct  5 17:08 titi │
      └───────┘    │-rw-r--r--   1 pm     essai     135 Oct  5 17:08 toto │
                   │-rw-r--r--   1 pm     essai       0 Oct  5 17:56 toto │
                   │-rw-r--r--   1 pm     essai     122 Oct  5 17:08 tutu │
                   └──────────────────────────────────────────────────────┘
    

    Cet affichage pourrait faire penser qu'il y a deux fichiers 'toto'.

    Pour visualiser les noms réels, on peut utiliser l'option '-b' qui affiche tout caractère non ASCII sous la forme octale '\0ooo'
     ┌──────────┐ ┌───────────────────────────────────────────────────────────┐
     │ ls -b t* │ │-rw-r--r--   1 pm     essai   128 Oct  5 17:08 titi        │
     └──────────┘ │-rw-r--r--   1 pm     essai   135 Oct  5 17:08 toto        │
                  │-rw-r--r--   1 pm     essai     0 Oct  5 17:56 toto\033[=N1│
                  │-rw-r--r--   1 pm     essai   122 Oct  5 17:08 tutu        │
                  └───────────────────────────────────────────────────────────┘
    

    L'option '-b' a fait apparaître '\033' à la place du code 'ESC', et l'on peut voir que lors de sa création le nom du fichier a en fait été validé par la touche fonction 'ESC[=N1' et non pas 'CR' ou 'RETURN'.

    On peut aussi utiliser l'option '-q' qui affiche un '?' pour chaque caractère non ASCII.

     ┌──────────┐  ┌───────────────────────────────────────────────────────────┐
     │ ls -q t* │  │-rw-r--r--   1 pm     essai   128 Oct  5 17:08 titi        │
     └──────────┘  │-rw-r--r--   1 pm     essai   135 Oct  5 17:08 toto        │
                   │-rw-r--r--   1 pm     essai     0 Oct  5 17:56 toto?[=N1   │
                   │-rw-r--r--   1 pm     essai   122 Oct  5 17:08 tutu        │
                   └───────────────────────────────────────────────────────────┘
    

     ┌──────────────────┐
     │ ls -q | grep '?' │  Permet d'afficher tous les noms de fichiers qui
     └──────────────────┘    comportent au moins un caractère non ASCII.
    

    Si l'on utilise le '?' comme caractère dans un nom de fichier (Exemple '>toto?' crée un fichier 'toto?' puisque l'interprétation du '?' par le SHELL ne s'étend pas aux re-directions (Voir SHELL)), ces fichiers ressortiront aussi en anomalie.

    Une bonne habitude pour les noms de fichiers consiste à se limiter aux caractères alphanumériques [A-Za-z0-9] et éventuellement le '_' et peut-être encore des '.' ou '-' et dans ce cas le SHELL peut aussi aider à retrouver des anomalies.

      ┌─────────────────────────┐
      │ ls -b *[!A-Za-z0-9_.-]* │  Permet d'afficher uniquement les noms des
      └─────────────────────────┘    fichiers qui comportent d'autres
    

    caractères que ceux indiqués entre '[!...]'. (Voir SHELL).

           ┌────────────────────────────────────────────────────────────┐
           │-rw-r--r--   1 pm     essai     0 Oct  5 17:56 toto\033[=N1 │
           └────────────────────────────────────────────────────────────┘
    




     6 : SECURITE SOUS SHELL   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Il y a plusieurs points à surveiller lors de la mise en place, de l'administration ou l'exploitation d'un système LINUX.

    Le super-utilisateur a tous les droits y compris de se détruire lui-même et de détruire tout ou partie d'un répertoire, d'une partition.

    En conséquence il ne faudra jamais être sous root en permanence.

    Surfer sur Internet sous 'root' pourrait avoir aussi de graves conséquences s'il y avait des failles de sécurité dans le navigateur (surtout si l'on ajoute au navigateur des plugins mal intentionnés).

    Ne jamais installer de paquets dont l'origine et les intentions pourraient être douteuse

    Sous un utilisateur non root une faute de frappe peut avoir des conséquences graves (pour lui même) , mais sous root elles peuvent même empêcher le re-démarrage du système.

    Exemple si un utilisateur veut effacer ses fichiers situés dans son répertoire test/bin :

               La coommande pourait être 
               rm -f /home/xxxx/test/bin/*
               Mais si l'opérateur compose :
               rm -f /home/xxxx/test /bin/*
               Je vous laisse imaginer les conséquences si on lance ceci sous root.
    

    Que celui qui n'a jamais fait une faute de frappe essaie d'en faire sous root.

    cela ne veut pas dire qu'il ne faudra jamais aller sous 'root' pour exécuter des commandes d'administration qui nécéssitent

    Sans être paranoïaque de la sécurité, il faut aussi surveiller les serveurs d'un façon plus pointue qu'une station de travail avec un seul utilisateur qui est en même temps administrateur.

    Sur un serveur :

    Le mot de passe de root ne doit être communiqué qu'à des personnes de confiance, et doit être modifié régulièrement.

    Si des personnes n'ayant pas connaissance du mot de passe de root doivent lancer telle ou telle commandes régulièrement, il suffira de leur définir des droits d'exécution de ces commandes avec sudo.

    Exemple :

              Un développeur SQL aura peut-être besoin de re-démarrer/recharger le serveur SQL sans pour autant avoir tous les
    droits par ailleurs.  Il suffira de lui attribuer la commande «service mysqld xxx» dans le paramétrage sudo
    




     6.1 : COMMANDES su et sudo   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ces commandes sont souvent confondues et la façon d'utiliser sudo de certaines distributions augmente cette confusion.



    Il faudra donc bien distinguer le mot de passe que l'on doit saisir selon que l'on appelle avec
      su   ::= Le mot de passe demandé est le mot de passe de l'utilisateur demandé.
    
      sudo ::= Le mot de passe demandé est celui de l'utilisateur demandeur. 
                 Et cette saisie peut être facultative (intéressant pour un script).
    



    su enregistre dans le log /var/log/secure :
    Tous les accès infructueux.
    Les heures de début et de fin d'exécution
    sudo enregistre dans le log /var/log/secure :
    Tous les accès infructueux.
    Les commandes exécutées avec le nom du demandeur




     6.2 : su EXEC. D'UN SHELL/D'UNE CDE SOUS UNE AUTRE ID.   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    SYNOPSIS
        ┌───────────────────────────────────────────────────┐
        │ su [ options] [nom_utilisateur]                   │
        └───────────────────────────────────────────────────┘
    

    La commande su n'est pas l'abréviation de «superuser» mais de «substitute user», bien quelle soit utilisée le plus souvent pour passer sous 'root', elle permet aussi de passer sous une autre identité que root.

    su est plutôt orienté lancement de session, mais l'option '-c' permettra d'exécuter une simple commande.

    sudo est plutôt orienté lancement de commande, mais l'option '-s' permettra d'ouvrir une session shell.

    Ouvre un SHELL avec l'identité de l'utilisateur spécifié (si aucun utilisateur n'est spécifié, ce sera l'identité root qui sera prise par défaut).

    -, -l, --login Le shell est créé comme lors d'un 'login', donc l'environnement est VRAIMENT CELUI DE L'UTILISATEUR

    -c, --command=COMMANDE Exécute la commande spécifiée sous l'identité spécifiée (ou root par défaut).

    --session-command=COMMANDE Exécute la commande spécifiée mais sans créer une nouvelle session.

    -f, --fast Passe l'argument '-f' au shell (Uniquement pour csh o tcsh)

    -m, --preserve-environment Ne réinitialise pas les variables d'environnement.

    -p Identique à l'option '-m'

    -s, --shell=SHELL Executé le shell spécifié si le fichier /etc/shells l'autorise

    --help Affiche cette aide.

    --version Affiche le numéro de version de su.

    ATTENTION : Un petit tiret vous manque et rien ne marche comme on le voudrait.

    Souvent par paresse ou ignorance, un utilisateur confond l'utilisation de 'su' avec ou sans '-'.

    Or la différence est importante.

    Prenons l'exemple d'un utilisateur non root qui utilise :

                  su   ::=  On passe bien sous root. Mais le PATH reste le PATH de l'utilisateur 
                                et donc on n'a pas accès aux commandes d'administration de root.
                  su - ::=  On passe bien sous root, mais comme lors d'un login, 
                                donc on passe par les scripts d'initialisation des variables de root 
                                et le PATH sera celui de root et permettra un accès aux commandes 
                                d'administration.
    
    

    Pour plus d'informations, voir la commande su.




     6.3 : sudo EXEC. D'UNE CDE/D'UN SHELL SOUS UNE AUTRE ID.   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Si le lecteur de ce chapitre a déjà lu le chapitre consacré à su, il pourra remarquer la différence d'intitulé.

    sudo est plutôt orienté lancement de commande, mais l'option '-s' permettra d'ouvrir une session shell.

    sudoedit est un lien sur sudo. Comme son nom l'indique sudoedit va permettre d'éditer un fichier sans être obligé de composer la commande «sudo nom_editeur nom_fichier». Cela correspond à l'option '-e' du sudo.

    SYNOPSIS
        sudo -h | -K | -k | -L | -l | -V | -v
    
        sudo [-bEHPS] [-p prompt] [-r role] [-t type] [-u username|#uid] [VAR=value] {-i | -s | commande}
    
        sudoedit [-S] [-p prompt] [-u username|#uid] fichier ...   
    
    

    DESCRIPTION

    sudo permet à un utilisateur d'exécuter une commande en tant que super-utilisateur (root) ou d'un autre utilisateur.

    Pour pouvoir utiliser sudo, un utilisateur, la ou les commandes auxquelles a droit un demandeur, la liste des utilisateurs demandés doivent être paramétrés dans un fichier /etc/sudoers maintenu par la commande visudo.

    Selon le paramétrage dans sudoers, le demandeur devra s'authentifier avec son propre mot de passe pour s'identifier.

    Une fois l'authentification réalisée, l'utilisateur pourra relancer des commandes sans avoir à ressaisir son mot de passe.

    Au bout d'un certain temps (timer) sans utilisation de sudo il devra à nouveau s'identifier.

    La commande sudoedit correspond à sudo -e.

    Exemples :

                    sudo commande                      par défaut root
                    sudo -u login_demandé commande     le demandeur demande à exécuter la commande sous le login_demandé
                    sudo -l                            affichage des commandes autorisées/interdites. 
    

    OPTIONS

    sudo accepte les options suivantes :

    Si l'on désire positionner des variables d'environnement, on pourra utiliser la syntaxe VAR=valeur




    Un utilisateur pourra voir les spécificités qui lui sont définies avec la commande sudo -l
    $ sudo -l
    User ludwig may run the following commands on this host:
        (root) NOPASSWD: /bin/umount /CDROM
        (root) NOPASSWD: /bin/mount -o nosuid,nodev /dev/cdrom /CDROM
        (root) NOPASSWD: /sbin/service mysqld *
        (mysql) NOPASSWD: ALL
    






     6.3.1 : visudo PARAMETRAGE sudo /etc/sudoers   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Le paramétrage de sudo se trouve dans le fichier /etc/sudoers, mais comme sa syntaxe doit être contrôlée, pour garantir un bon fonctionnement, il ne faudra jamais éditer ce fichier directement avec un éditeur, mais il faudra passer par la commande visudo.

    Pour des raisons de sécurité visudo n'est utilisable que sous root (sauf si avec visudo on accorde le droit à un autre utilisateur de faire un sudo visudo).

    La commande visudo appelle un editeur qui par défaut est vi, et peut (s'il a été compilé pour) utiliser un autre éditeur spécifié dans la variable SHELL !VISUAL! ou !EDITOR!.

    Lorsque l'on sort de l'éditeur appelé par visudo, visudo vérifie la syntaxe du fichier /etc/sudoers et vous proposera de retourner dans l'éditeur pour corriger, à moins que vous ne vouliez abandonner.

    Mais dans le cas d'un fichier /etc/sudoers syntaxiquement incorrect, la commande sudo ne pourra plus fonctionner et les autres utilisateurs ne pourront pas exécuter, même des spécification correctes.

    Un utilisateur pourra voir les spécificités qui lui sont définies avec la commande sudo -l
    $ sudo -l
    User ludwig may run the following commands on this host:
        (root) NOPASSWD: /bin/umount /CDROM
        (root) NOPASSWD: /bin/mount -o nosuid,nodev /dev/cdrom /CDROM
        (root) NOPASSWD: /sbin/service mysqld *
        (mysql) NOPASSWD: ALL
    

    La présente documentation (tirée du man officiel) utilise la norme EBNF (L'Extended Backus-Naur Form) qui est courante pour définir des éléments complexes en les décomposant en sous-éléments et ceci sur n niveaux jusqu'à un niveau élémentaire (atomique).

             Element ::= Sous_elem1 Sous_elem2 
             Sous_elem1 ::= Sous_sous_elem1 
             .......
    



    Dans un fichier sudoers on trouvera des définitions d'alias et des spécifications utilisateurs.
    C'est chaque ligne utilisateur qui utilisera des alias pour définir qui aura le droit de faire quoi et comment.


    Alias

    Il y a quatre sortes d'alias dans les paramètres sudoers : User_Alias, Runas_Alias, Host_Alias and Cmnd_Alias.

           Alias ::= 'User_Alias'  User_Alias  (':' User_Alias)*  |
                     'Runas_Alias' Runas_Alias (':' Runas_Alias)* |
                     'Host_Alias'  Host_Alias  (':' Host_Alias)*  |
                     'Cmnd_Alias'  Cmnd_Alias  (':' Cmnd_Alias)*
          
           User_Alias  ::= NAME '=' User_List
          
           Runas_Alias ::= NAME '=' Runas_List
          
           Host_Alias  ::= NAME '=' Host_List
          
           Cmnd_Alias  ::= NAME '=' Cmnd_List
    



    Spécification_Utilisateur

    Cette section, la plus importante, permet de donner effectivement les droits à un utilisateur.

    Vous pouvez remarquer que par défaut une ligne est déjà présente.

    Elle concerne l'utilisateur root qui a droit à tout, partout, tout le temps.

    Il est préférable de ne pas la modifier.

    On peut se demander pourquoi root utiliserait sudo. Mais on peut imaginer que 'root' prépare un script utilisant 'sudo' car il sera par la suite utilisée par d'autre utilisateurs.

    Regardons la ligne de root pour en déduire ce que l'on pourra utiliser pour d'autres utilisateurs:




    EXEMPLES Vous désirez que l'utilisateur 'wolfgang' dispose des droits de l'utilisateur 'ludwig', il faut définir une ligne comme celle-ci :
                wolfgang ALL=(ludwig) ALL
                     │    │    │       |
                     │    │    │       └─── Liste_commandes     ::= ALL                   wolfgang pourra utiliser toutes les commandes auxquelles à accès ludwig.
                     │    │    └─────────── Runas               ::= ludwigs               wolfgang ne pourra pas demander à être un autre utilisateur que ludwig
                     │    └──────────────── Liste_hosts         ::= ALL                   Sur toutes les machines
                     └───────────────────── Liste_utilisateurs  ::= wolfgang              wolfgang est le seul utilisateur demandeur de cette spécification.
    
    

    Cette spécification signifie que pour toutes les commandes que va taper wolfgang (avec sudo) cumuleront ses droits à lui et ceux de ludwig.

    Plus concrètement il pourra faire tout ce que peut faire ludwig.



    Même chose mais on évite à wolfgang de saisir à chaque fois son propre mot de passe.

    
    
                wolfgang ALL=(ludwig) NOPASSWD:ALL
                     │    │    │          │     |
                     │    │    │          │     └─── Liste_commandes     ::= ALL                   wolfgang pourra utiliser toutes les commandes auxquelles à accès ludwig.
                     │    │    │          └───────── Tag                 ::= Pas de mot de passe   wolfgang n'aura pas besoin de saisir son mot de passe pour s'authentifier.
                     │    │    │                                                                   Si wolfgang laisse son poste pour aller boire un café ...... 
                     │    │    └──────────────────── Runas               ::= lugwig                wolfgang ne pourra pas demander à être un autre utilisateur que ludwig
                     │    └───────────────────────── Liste_hosts         ::= ALL                   Sur toutes les machines
                     └────────────────────────────── Liste_utilisateurs  ::= wolfgang              wolfgang est le seul utilisateur demandeur de cette spécification.
    
    



    Cette spécification permettra à tous les utilisateurs de monter ou démonter le CDROM.

    
       ALL ALL =        NOPASSWD:/sbin/umount /CDROM,/sbin/mount -o nosuid\,nodev /dev/cdrom /CDROM
       │    │       │       │     |
       │    │       │       │     └─── Liste_commandes     ::= Séparateur ,         Seules les commandes mount xxxx et umount yyyyyy sont accessibles.
       │    │       │       │                                                        A noter le \, pour ne pas confondre avec une séparation de commandes.
       │    │       │       └───────── Tag                 ::= Pas de mot de passe   Les utilisateurs n'auront pas besoin de saisir leurs propres mots de passe
       │    │       │                                                                  pour s'authentifier.
       │    │       └───────────────── Runas               ::= Aucune spécification  Donc, par défaut, root sera toujours le seul demandé (demandable).
       │    │                                                                        De toute façon mount et umount ne seraient pas utilisables par d'autres.
       │    └───────────────────────── Liste_hosts         ::= ALL                   Sur toutes les machines
       └────────────────────────────── Liste_utilisateurs  ::= ALL                   Tous les utilisateurs pourront monter/démonter le cdrom.
    
       N'importe quel utilisateur pourra lancer sudo mount -o nosuid,nodev /dev/cdrom /CDROM ou sudo umount /CDROM i
        mais pas d'autres options, ni paramètres de mount/umount.
    



    Cette spécification permettra à l'utilisateur !racine¡ de modifier les mots de passe utilisateur sans pouvoir modifier celui de root.

        racine  ALL =      /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
           │    │       │       |
           │    │       │       └───────── Liste_commandes     ::= Séparateur ,          A noter la négation par '!' pour interdire l'utilisation de la 
           │    │       │                                                                  modification du mot de passe de root.
           │    │       └───────────────── Runas               ::= Aucune spécification  Donc, par défaut, root sera toujours le seul demandé (demandable).
           │    │                                                                        De toute façon c'est le but.
           │    └───────────────────────── Liste_hosts         ::= ALL                   Sur toutes les machines
           └────────────────────────────── Liste_utilisateurs  ::= ALL                   Seul racine pourra modifier les mots de passe des utilisateurs
                                                                                           non root.
        
    
    



    Runas_Alias DB = mysql, postgres

    ludwig ALL = (DB) NOPASSWD: ALL
                  │    │       │       |
                  │    │       │       └───────── Liste_commandes     ::= ALL      Toutes les commandes                                            
                  │    │       │                                                                                          
                  │    │       └───────────────── Runas               ::= DB       Donc ludwig pourra demander à être mysql ou postgres   
                  │    │                                                             avec par exemple 'sudo -i mysql commande'.
                  │    │                                                           Mais il ne pourra pas demander à être root.
                  │    └───────────────────────── Liste_hosts         ::= ALL      Sur toutes les machines
                  └────────────────────────────── Liste_utilisateurs  ::= ludwig   Seul ludwig pourra utiliser cette spécification               
    

    Jokers

    sudo accepte des jokers semblables à ceux du shell pour les chemins de fichiers mais aussi pour les lignes de commande dans le fichier sudoers.

    Ces jokers respectent la fonction fnmatch(3) de la norme POSIX.

    ATTENTION : ce ne sont pas des expressions régulières, mais des caractères jokers.


    Noter que le slash interrompt la recherche de correspondance de façon à ne pas faire une recherche de correspondance récursive :

    /usr/bin/* correspond à /usr/bin/who mais pas à /usr/bin/X11/xterm.




    Pour plus d'informations, voir la commande visudo et le fichier /etc/sudoers.




     7 : EXEMPLES DE SCRIPTS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre a pour objet de présenter des exemples simples et commentés de scripts SHELL utilisant les instructions de base du SHELL ainsi que les commandes de base vues dans ce manuel.

    Les scripts sont donnés à titre d'exemple et doivent être considérés comme tels. En particulier il peut y avoir différentes façons de résoudre un problème et lorsque cela sera intéressant il pourra y avoir différents scripts présentés pour résoudre le même problème.




     7.1 : EXPLOITATION D'UN PATH   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    But du script : Afficher sur la sortie standard la totalité des commandes (scripts ou programmes exécutables) contenues dans les différents répertoires contenus dans la variable $PATH.

    L'argument 1 d'appel sera une suite de caractères ou méta-caractères du SHELL afin de pouvoir faire une sélection sur les noms de commande.

    En absence d'argument la totalité des répertoires sera traitée.

     ┌──────────────────────────────────────────────────────────────────────────┐
     │ arg=${1:-*}                                                              │
     │ fichier_tmp=/tmp/liste$$                                                 │
     │ >$fichier_tmp                                                            │
     │ for repert in `echo $PATH | sed -e 's/::/:.:/' | sed -e 's/:/ /g'`       │
     │ do                                                                       │
     │   for nom_fic in `ls -dF1 $repert/$arg 2>/dev/null | sed -n -e 's/\*//p'`│
     │   do                                                                     │
     │     if [ -x $nom_fic ]                                                   │
     │       then                                                               │
     │         nomfic=`basename $nom_fic`                                       │
     │         printf '%-16s %s\n' $nomfic $nom_fic >>$fichier_tmp              │
     │     fi                                                                   │
     │   done                                                                   │
     │ done                                                                     │
     │ cat $fichier_tmp | sort                                                  │
     │ rm $fichier_tmp                                                          │
     └──────────────────────────────────────────────────────────────────────────┘
    

    arg=${1:-*} ::= Substitution du caractère '*' en cas d'absence de contenu de $1 (argument permettant une sélection sur les noms de commandes)
     ┌─────────────────────────┐
     │fichier_tmp=/tmp/liste$$ │
     │>$fichier_tmp            │::= Construction d'un fichier manoeuvre dans
     └─────────────────────────┘     "/tmp" de nom "liste" suivi du numéro de
    

    processus.

     ┌───────────────────────────────────────────────────────────────────┐
     │for repert in `echo $PATH | sed -e 's/::/:.:/' | sed -e 's/:/ /g'` │
     └───────────────────────────────────────────────────────────────────┘
    

    Eclatement par 'sed' du contenu de $PATH avec transformation du "::" en ":.:" puis transformation des ':' en ' '. Ceci pour passer en arguments séparés par des espaces chaque répertoire contenu dans $PATH.

     ┌─────────────────────────────────┐
     │ls -dF1 $repert/$arg 2>/dev/null │
     └─────────────────────────────────┘
    

    Liste des fichiers exécutables -F ::= Affichage avec un '*' en fin de nom des fichiers exécutables.

    -1 ::= Affichage d'un nom par ligne -d ::= Ne pas exploiter le contenu de sous-répertoires.

    2>/dev/null ::= Ignorer l'absence de fichiers correspondant à la sélection pour un 'ls' dans un répertoire contenu dans $PATH.

     ┌───────────────────┐
     │sed -n -e 's/\*//p'│ ::= Récupération des noms de fichiers contenant
     └───────────────────┘       un '*' (résultat de l'option '-F' de 'ls' pour
    

    un exécutable. A noter le '\*' pour spécifier le caractère '*'.

     ┌───────────────────┐
     │if [ -x $nom_fic ] │ ::= Test que l'exécutable obtenu par 'ls' est bien
     └───────────────────┘       exécutable par l'utilisateur.
    

     ┌──────────────────────────┐
     │nomfic=`basename $nom_fic`│::= Récupération du nom de l'exécutable sans
     └──────────────────────────┘     le nom du répertoire.
    

     ┌───────────────────────────────────────────────────┐
     │printf '%-16s %s\n' $nomfic $nom_fic >>$fichier_tmp│
     └───────────────────────────────────────────────────┘
    

    ::= Impression sur 16 caractères du nom du fichier suivi du path complet de ce fichier dans le fichier temporaire.

     ┌───────────────────────┐
     │cat $fichier_tmp | sort│   ::= Tri du fichier temporaire et affichage du
     └───────────────────────┘        résultat de tri sur la sortie standard.
    

     ┌───────────────┐
     │rm $fichier_tmp│           ::= Destruction du fichier temporaire.
     └───────────────┘
    

    VARIANTE

    Dans cette variante on utilise un 'ls' simple de chaque répertoire et l'on réalise directement une test [ -x $nom_fic ] sur chaque fichier contenu dans le répertoire. Ce qui fait que si un répertoire contient un grand nombre de fichiers non exécutables la recherche des exécutables sera peut-être plus lente que l'ensemble 'ls -F' + 'sed -e'.

    La mise en page n'utilise pas 'printf' mais un test sur la longueur de chaque nom de fichier afin de savoir si l'on affiche une ou deux tabulations entre le nom du fichier et son path complet.

     ┌────────────────────────────────────────────────────────────────────┐
     │ arg=${1-*}                                                         │
     │ >/tmp/liste$$                                                      │
     │ for repert in `echo $PATH | sed -e 's/::/:.:/' | sed -e 's/:/ /g'` │
     │ do                                                                 │
     │    for nom_fic in `ls -d $repert/$arg 2>/dev/null `                │
     │    do                                                              │
     │      if [ -x $nom_fic ]                                            │
     │      then                                                          │
     │         nomfic=`basename $nom_fic`                                 │
     │         if [ `expr $nomfic : '.*'` -le 6 ]                         │
     │           then tab=\\t\\t                                          │
     │           else tab=\\t                                             │
     │         fi                                                         │
     │      echo $nomfic $tab $nom_fic >>/tmp/liste$$                     │
     │      fi                                                            │
     │    done                                                            │
     │ done                                                               │
     │ cat /tmp/liste$$ | sort                                            │
     │ rm /tmp/liste$$                                                    │
     └────────────────────────────────────────────────────────────────────┘
    




     7.2 : AMELIORATION PRESENTATION 'ls'   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    La commande 'ls' permet d'afficher les noms des fichiers désirés mais si l'on s'intéresse au type de fichier il faut alors demander une option '-F' qui permet d'obtenir un '/' , un '*' ou un '@' à la fin de chaque fichier traité si il s'agit d'un répertoire, d'un exécutable ou d'un lien symbolique. Mais ces caractères ne sont pas toujours très visibles sur une page entière d'écran. La commande à réaliser ici fera appel à des séquences 'ESC' qui permettent de changer l'attribut d'affichage écran comme le souligné, la faible intensité lumineuse ou encore l'inverse-vidéo.

    Le résultat de 'ls' étant redirigé par un 'pipe' on utilisera l'option '-C' de 'ls' pour garder un affichage en colonnes. De plus on utilisera l'option '-q' pour afficher les caractères non ASCII contenus dans certains noms de fichiers.

    L'encadrement des noms de fichiers par des séquences appropriées (activation puis désactivation de l'attribut choisi) se fera avec la commande 'sed' qui recevra trois demandes de substitution pour les trois caractères (/$, * ou @) correspondant au type de fichier.

    Les caractères '*' et '@' seront remplacés par des espaces alors que l'on gardera le '/'.

    Le caractère '/' étant utilisé dans les recherches à effectuer on utilisera le caractère '|' comme séparateur d'expression régulière et de chaîne de remplacement dans la commande 'substitute' de 'sed'.

    L'encadrement des noms à traiter se fera en utilisant l'encadrement de l'expression régulière par '\(' et '\)' et en utilisant '\1' pour spécifier la chaîne trouvée en correspondance à cette expression.

    Comme l'espacement des noms de fichiers est réalisé par des espaces il suffit de rechercher le premier caractère non espace ([^ ]) suivi de zéro ou n autres caractères non espace '*'. Cette expression '[^ ]*' sera encadrée par des '\(' et '\)' et suivie de caractère '/', '*' ou '@' désiré. (A noter que pour le '*' on est obligé d'utiliser '\*' car le '*' est un caractère spécial des expressions régulières). Chaque fois qu'une chaîne de caractères non espace sera trouvée devant un des caractères '/', '*' ou '@' la spécification '\1' permettra d'obtenir la chaîne concernée que l'on pourra donc encadrer par des séquences d'attribut.

    Le caractère 'ESC' (\033 ou h1b) est initialisé par un 'echo "\033"' puisque la commande 'sed' ne reconnaît pas les '\0ooo'.

    Les séquences d'attribut utilisées sont au standard 'vt220'

    En début de programme on utilise un 'trap' qui permettra de réinitialiser l'écran si le déroulement était interrompu (CTRL+C, coupure de ligne, etc...).

      ┌─────────────────────────────────────────────────────────────┐
      │  trap 'echo "\033[m\c"' 0 1 2                               │
      │  ESC=`echo "\033"`  # Initialisation du caractère ESC       │
      │  EXEC1=$ESC[4m      # Sous-ligné                            │
      │  EXEC0=$ESC[24m     # Suppression souligné                  │
      │  REP1=$ESC[7m       # Inverse vidéo                         │
      │  REP0=$ESC[27m      # Suppression inverse vidéo             │
      │  LINK1=$ESC[1m      # Faible intensité lumineuse            │
      │  LINK0=$ESC[22m     # Forte intensité lumineuse             │
      │                                                             │
      │  ls -CFq "$@" |                                             │
      │  sed "s|\([^ ]*\)\*|$EXEC1\1$EXEC0 |g                       │
      │       s|\([^ ]*\)/|$REP1\1/$REP0|g                          │
      │       s|\([^ ]*\)@|$LINK1\1$LINK0 |g"                       │
      │                                                             │
      └─────────────────────────────────────────────────────────────┘
    

    Résultat :

         ┌────────────────────────────────────────────────────────┐
         │  fichier1   fichier3   prog2      repert1    repert3   │
         │  fichier2   prog1      prog3      repert2              │
         └────────────────────────────────────────────────────────┘
    

    VARIANTE POUR ECRAN ou IMPRIMANTE IOCS Ce script testera si la sortie standard est un terminal et dans le cas contraire considérera qu'il s'agit d'une sortie vers un fichier imprimable ou d'une imprimante. Dans ce cas les séquences d'attribut seront des séquences et l'inverse-vidéo sera remplacé par l'attribut 'caractère gras' et la faible luminosité par 'gras+souligné'.

    A noter la syntaxe de définition de 'ESC+E' ou 'ESC+F' qui demande des '{}' pour éviter l'ambiguïté avec un nom de variable '$ESCE' ou '$ESCF'.

      ┌─────────────────────────────────────────────────────────────────┐
      │  ESC=`echo "\033"`  # Initialisation du caractère ESC           │
      │  if [ -t 1 ]           # Test sortie tty ou fichier             │
      │   then                                                          │
      │     trap 'echo "\033[m\c"' 0 1 2                                │
      │     EXEC1=$ESC[4m      # Sous-ligné                             │
      │     EXEC0=$ESC[24m     # Suppression souligné                   │
      │     REP1=$ESC[7m       # Inverse vidéo                          │
      │     REP0=$ESC[27m      # Suppression inverse vidéo              │
      │     LINK1=$ESC[1m      # Faible intensité lumineuse             │
      │     LINK0=$ESC[22m     # Forte intensité lumineuse              │
      │   else                                                          │
      │     EXEC1=$ESC-1        # Sous-ligné                            │
      │     EXEC0=$ESC-0        # Suppression souligné                  │
      │     REP1=${ESC}E        # Gras                                  │
      │     REP0=${ESC}F        # Suppression gras                      │
      │     LINK1=$ESC-1${ESC}E # Gras+souligné                         │
      │     LINK0=$ESC-0${ESC}F # Suppression gras+souligné             │
      │  fi                                                             │
      │  ls -CFq "$@" |                                                 │
      │  sed "s|\([^ ]*\)\*|$EXEC1\1$EXEC0 |g                           │
      │       s|\([^ ]*\)/|$REP1\1/$REP0|g                              │
      │       s|\([^ ]*\)@|$LINK1\1$LINK0 |g"                           │
      └─────────────────────────────────────────────────────────────────┘
    




     7.3 : AFFICHAGE VALEURS ASCII 0=>255   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce script permet d'afficher sur la sortie standard les valeurs décimales, octales et hexadécimales ainsi que le caractère correspondant pour les valeurs de 0 à 255.

    On utilise une boucle 'while', des tests [ ... ] , la commande 'bc' pour effectuer les conversions (décimal => octal et décimal => hexadécimal) et la commande 'printf' pour améliorer la présentation que pourrait faire 'echo'.

     ┌─────────────────────────────────────────────────────────────────────────┐
     │ i=0                                # Initialisation compteur            │
     │ while  [ $i -le 255 ]                                                   │
     │ do                                                                      │
     │  octal=`echo "obase=8\n$i" | bc`   # récupération valeur octale         │
     │  hexa=`echo "obase=16\n$i" | bc`   # récupération valeur hexadécimale   │
     │  if ( [ $i -gt 32 ] && [ $i -le 127 ] ) || [ $i -ge 160 ]               │
     │  then                                                                   │
     │    caract=`echo "\0$octal"`        # récup. caractère affichable        │
     │  else                                                                   │
     │    j=`expr $i + 64`                # récup. caractère de contrôle       │
     │    octalb=`echo "obase=8\n$j" | bc`                                     │
     │    caract=`echo "^\0$octalb"`                                           │
     │  fi                                                                     │
     │  printf '%3s %3s %2s %-2s    '  $i $octal $hexa "$caract"               │
     │  i=`expr $i + 1`                                                        │
     │  j=`expr $i % 4`                   # test passage à la ligne            │
     │  if [ $j -eq 0 ]                                                        │
     │  then                                                                   │
     │    echo                                                                 │
     │  fi                                                                     │
     │ done                                                                    │
     └─────────────────────────────────────────────────────────────────────────┘
    




     7.4 : COPIE DE FICHIERS AVEC CHANGEMENT DE NOM   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Si l'on désire obtenir un double de certains fichiers (Exemple : un jeu d'essai), en les copiant sous un autre nom, le SHELL offre de nombreuses possibilités.

    En fin de traitement on se trouvera donc en présence d'une copie du jeu d'essai d'origine mais sous un autre nom.

    Dans cet exemple, on considère que les fichiers se termine par un radical indiquant le numéro de société ou de jeu d'essai. Les fichiers d'origine finissent tous par '098' et l'on désire obtenir un double de tous ces fichiers dans le même répertoire avec le radical de fin '099'.

    Exemple : On veut partir copier les fichiers :

                ┌────────────────────────────────┐
                │  GF-03000098  =>  GF-03000099  │
                │  GF-03100098  =>  GF-03100099  │
                │  GF-03200098  =>  GF-03200099  │
                │  etc....                       │
                └────────────────────────────────┘
    

    1er cas : Fichiers ayant des noms de même longueur de 11 caractères :

    Pour sélectionner les fichiers de cette longueur, on utilise 'ls ????????098' Pour obtenir le nom du fichier sans son radical on utilise la commande 'cut -c1-8'.

                 ┌───────────────────────────────────────────────────┐
                 │  for nom_fic in `ls ????????098`                  │
                 │  do                                               │
                 │      nom_fic_dest=`echo $nom_fic | cut -c1-8 `099 │
                 │      echo $nom_fic $nom_fic_dest                  │
                 │      cp $nom_fic $nom_fic_dest                    │
                 │  done                                             │
                 └───────────────────────────────────────────────────┘
    

    Variante en utilisant 'printf "%.8s"' à la place de 'cut' :

                 ┌───────────────────────────────────────────────────┐
                 │  for nom_fic in `ls ????????098`                  │
                 │  do                                               │
                 │      nom_fic_dest=`printf "%.8s $nom_fic`099      │
                 │      echo $nom_fic $nom_fic_dest                  │
                 │      cp $nom_fic $nom_fic_dest                    │
                 │  done                                             │
                 └───────────────────────────────────────────────────┘
    

    2ème cas : Fichiers ayant des noms de longueur variable mais on ne désire copier que ceux qui ont une longueur de 11 caractères et afficher un message pour les autres.

    On utilise 'ls *098' pour obtenir une liste de tous les fichiers finissant par '098'.

    On utilise 'expr' pour tester la longueur du nom.

    Pour les noms de 11 caractères, on utilise une autre forme de 'expr' pour extraire la partie du nom sans le radical.

    Pour les noms faisant plus ou moins de 11 caractères on affiche un message.

           ┌────────────────────────────────────────────────────────────┐
           │  for nom_fic in `ls *098`                                  │
           │  do                                                        │
           │     if [ `expr $nom_fic : .*098` -eq 11 ]                  │
           │     then                                                   │
           │       nom_fic_dest=`expr $nom_fic : '\(........\)098'`099  │
           │       echo $nom_fic $nom_fic_dest                          │
           │       cp $nom_fic $nom_fic_dest                            │
           │      else                                                  │
           │       echo $nom_fic "non copié"                            │
           │     fi                                                     │
           │  done                                                      │
           └────────────────────────────────────────────────────────────┘
    

    3ème cas : Fichiers ayant des noms de longueur variable mais que l'on désire copier quelque soit cette longueur On utilise 'basename' pour la recherche du nom sans le radical.

                  ┌─────────────────────────────────────────────┐
                  │ for nom_fic in `ls *098`                    │
                  │ do                                          │
                  │    nom_fic_dest=`basename $nom_fic 098`099  │
                  │    echo $nom_fic $nom_fic_dest              │
                  │    cp $nom_fic $nom_fic_dest                │
                  │ done                                        │
                  └─────────────────────────────────────────────┘
    

    4ème cas : Fichiers ayant des noms de longueur variable mais que l'on désire copier quelque soit cette longueur On utilise 'expr' pour la recherche du nom sans le radical.

    Pour être sûr que le nom de fichier soit correct même s'il contient un '098', la recherche de '098' se fait sous la forme '098$' qui spécifie que '098' est à rechercher en fin de ligne.

                  ┌───────────────────────────────────────────────────┐
                  │ for nom_fic in `ls *098`                          │
                  │ do                                                │
                  │    nom_fic_dest=`expr $nom_fic : '\(.*\)098$'`099 │
                  │    echo $nom_fic $nom_fic_dest                    │
                  │    cp $nom_fic $nom_fic_dest                      │
                  │ done                                              │
                  └───────────────────────────────────────────────────┘
    

    Variante en utilisant 'sed'
                  ┌───────────────────────────────────────────────────────┐
                  │ for nom_fic in `ls *098`                              │
                  │ do                                                    │
                  │    nom_fic_dest=`echo $nom_fic | sed -e 's/098/099/'` │
                  │    echo $nom_fic $nom_fic_dest                        │
                  │    cp $nom_fic $nom_fic_dest                          │
                  │ done                                                  │
                  └───────────────────────────────────────────────────────┘
    

    ATTENTION : Cet exemple ne fonctionne pas correctement si la racine '098' peut figurer au milieu du nom d'un fichier et non uniquement en fin, car 'sed' effectue le changement /098/099/ sur la première occurence de '098'.

    Pour pallier ce problème, on peut ajouter un '/' au nom de fichier et dans ce cas utiliser un autre séparateur pour les chaînes à remplacer et de remplacement et remplacer '098/' par '099'.

                  ┌─────────────────────────────────────────────────────────┐
                  │ for nom_fic in `ls *098`                                │
                  │ do                                                      │
                  │    nom_fic_dest=`echo $nom_fic/ | sed -e 's^098/^099^'` │
                  │    echo $nom_fic $nom_fic_dest                          │
                  │    cp $nom_fic $nom_fic_dest                            │
                  │ done                                                    │
                  └─────────────────────────────────────────────────────────┘
    

    On peur utiliser aussi une formulation plus complexe de la chaîne à remplacer et de la chaîne de remplacement en utilisant '\(...\)' et '\1' dans ces spécifications de chaînes :

           ┌────────────────────────────────────────────────────────────────┐
           │ for nom_fic in `ls *098`                                       │
           │ do                                                             │
           │    nom_fic_dest=`echo $nom_fic | sed -e 's/\(.*\)098$/\1099/'` │
           │    echo $nom_fic $nom_fic_dest                                 │
           │    cp $nom_fic $nom_fic_dest                                   │
           │ done                                                           │
           └────────────────────────────────────────────────────────────────┘
    

    5ème cas : Fichiers ayant des noms de longueur variable se trouvant dans le répertoire courant ou des sous-répertoire de celui-ci. Dans ce cas on considère que la copie xxxx098 et xxxx099 doit se faire dans le répertoire de chaque fichier source.

          ┌────────────────────────────────────────────────────┐
          │ for nom_fic in `find . -name "*098" -print`        │
          │ do                                                 │
          │    repert=`dirname $nom_fic`                       │
          │    nom_fic_dest=$repert/`basename $nom_fic 098`099 │
          │    echo $nom_fic $nom_fic_dest                     │
          │    cp $nom_fic $nom_fic_dest                       │
          │ done                                               │
          └────────────────────────────────────────────────────┘
    




     8 : ANNEXES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

    Ce chapitre est consacré aux annexes :

    Table ASCII




     8.1 : TABLE CODE ASCII   Début   Précédent   Sommaire   Préc.page.lue   Accueil

    Pour les autres tables (unicode, iso, cpxxx) voir le tutoriel tables codes

    La première colonne (0=>31) est constituée de caractères de contrôle dont la représentation '^x' correspond à la combinaison 'CTRL+x'

                                              ┌────────────────────┬────────────────┬─────────────────┬─────────────────┐
                                              │ déc oct hx         │ déc oct hx     │  déc oct hx     │ déc oct hx      │
                                              │   0 000 00 NUL  ^@ │  32 040 20 " " │   64 100 40  @  │  96 140 60  `   │
                                              │   1 001 01 SOH  ^A │  33 041 21  !  │   65 101 41  A  │  97 141 61  a   │
                                              │   2 002 02 STX  ^B │  34 042 22  "  │   66 102 42  B  │  98 142 62  b   │
                                              │   3 003 03 ETX  ^C │  35 043 23  #  │   67 103 43  C  │  99 143 63  c   │
                                              │   4 004 04 EOT  ^D │  36 044 24  $  │   68 104 44  D  │ 100 144 64  d   │
                                              │   5 005 05 ENQ  ^E │  37 045 25  %  │   69 105 45  E  │ 101 145 65  e   │
                                              │   6 006 06 ACK  ^F │  38 046 26  &  │   70 106 46  F  │ 102 146 66  f   │
                                              │   7 007 07 BEL  ^G │  39 047 27  '  │   71 107 47  G  │ 103 147 67  g   │
                                              │   8 010 08 BS   ^H │  40 050 28  (  │   72 110 48  H  │ 104 150 68  h   │
                                              │   9 011 09 HT   ^I │  41 051 29  )  │   73 111 49  I  │ 105 151 69  i   │
                                              │  10 012 0a LF   ^J │  42 052 2a  *  │   74 112 4a  J  │ 106 152 6a  j   │
                                              │  11 013 0b VT   ^K │  43 053 2b  +  │   75 113 4b  K  │ 107 153 6b  k   │
                                              │  12 014 0c FF   ^L │  44 054 2c  ,  │   76 114 4c  L  │ 108 154 6c  l   │
                                              │  13 015 0d CR   ^M │  45 055 2d  -  │   77 115 4d  M  │ 109 155 6d  m   │
                                              │  14 016 0e SO   ^N │  46 056 2e  .  │   78 116 4e  N  │ 110 156 6e  n   │
                                              │  15 017 0f SI   ^O │  47 057 2f  /  │   79 117 4f  O  │ 111 157 6f  o   │
                                              │  16 020 10 DLE  ^P │  48 060 30  0  │   80 120 50  P  │ 112 160 70  p   │
                                              │  17 021 11 DC1  ^Q │  49 061 31  1  │   81 121 51  Q  │ 113 161 71  q   │
                                              │  18 022 12 DC2  ^R │  50 062 32  2  │   82 122 52  R  │ 114 162 72  r   │
                                              │  19 023 13 DC3  ^S │  51 063 33  3  │   83 123 53  S  │ 115 163 73  s   │
                                              │  20 024 14 DC4  ^T │  52 064 34  4  │   84 124 54  T  │ 116 164 74  t   │
                                              │  21 025 15 NAK  ^U │  53 065 35  5  │   85 125 55  U  │ 117 165 75  u   │
                                              │  22 026 16 SYN  ^V │  54 066 36  6  │   86 126 56  V  │ 118 166 76  v   │
                                              │  23 027 17 ETB  ^W │  55 067 37  7  │   87 127 57  W  │ 119 167 77  w   │
                                              │  24 030 18 CAN  ^X │  56 070 38  8  │   88 130 58  X  │ 120 170 78  x   │
                                              │  25 031 19 EM   ^Y │  57 071 39  9  │   89 131 59  Y  │ 121 171 79  y   │
                                              │  26 032 1a SUB  ^Z │  58 072 3a  :  │   90 132 5a  Z  │ 122 172 7a  z   │
                                              │  27 033 1b ESC  ^[ │  59 073 3b  ;  │   91 133 5b  [  │ 123 173 7b  {   │
                                              │  28 034 1c FS   ^\ │  60 074 3c  <  │   92 134 5c  \  │ 124 174 7c  |   │
                                              │  29 035 1d GS   ^] │  61 075 3d  =  │   93 135 5d  ]  │ 125 154 7d  }   │
                                              │  30 036 1e RS   ^^ │  62 076 3e  >  │   94 136 5e  ^  │ 126 176 7e  ~   │
                                              │  31 037 1f US   ^_ │  63 077 3f  ?  │   95 137 5f  _  │ 127 177 7f DEL  │
                                              └────────────────────┴────────────────┴─────────────────┴─────────────────┘
    

                                              ┌──────────────────────────────────────────────────────────┐
                                              │   0 000 00 NUL  ^@  ::= Byte-null                        │
                                              │   1 001 01 SOH  ^A  ::= Début d'en-tête                  │
                                              │   2 002 02 STX  ^B  ::= Début de texte                   │
                                              │   3 003 03 ETX  ^C  ::= Fin de texte                     │
                                              │   4 004 04 EOT  ^D  ::= Fin de transmission              │
                                              │   5 005 05 ENQ  ^E  ::= Demande d'acquittement           │
                                              │   6 006 06 ACK  ^F  ::= Acquittement                     │
                                              │   7 007 07 BEL  ^G  ::= Sonnette                         │
                                              │   8 010 08 BS   ^H  ::= Retour arrière d'un caractère    │
                                              │   9 011 09 HT   ^I  ::= Tabulation horizontale           │
                                              │  10 012 0a LF   ^J  ::= Passage à la ligne               │
                                              │  11 013 0b VT   ^K  ::= Tabulation verticale             │
                                              │  12 014 0c FF   ^L  ::= Saut de page                     │
                                              │  13 015 0d CR   ^M  ::= Retour chariot                   │
                                              │  14 016 0e SO   ^N  ::= Shift out                        │
                                              │  15 017 0f SI   ^O  ::= Shift in                         │
                                              │  16 020 10 DLE  ^P  ::= Data link Escape                 │
                                              │  17 021 11 DC1  ^Q  ::= Device control 1  (X/ON)         │
                                              │  18 022 12 DC2  ^R  ::= Device control 2                 │
                                              │  19 023 13 DC3  ^S  ::= Device control 3  (X/OFF)        │
                                              │  20 024 14 DC4  ^T  ::= Device control 4                 │
                                              │  21 025 15 NAK  ^U  ::= Acquittement négatif             │
                                              │  22 026 16 SYN  ^V  ::= Caractère de synchronisation     │
                                              │  23 027 17 ETB  ^W  ::= Fin de bloc                      │
                                              │  24 030 18 CAN  ^X  ::= Cancel (Annulation)              │
                                              │  25 031 19 EM   ^Y  ::= End of medium (Fin du support)   │
                                              │  26 032 1a SUB  ^Z  ::= Caractère de substitution        │
                                              │  27 033 1b ESC  ^[  ::= ESCape                           │
                                              │  28 034 1c FS   ^\  ::= Séparateur de fichiers           │
                                              │  29 035 1d GS   ^]  ::= Séparateur de groupes            │
                                              │  30 036 1e RS   ^^  ::= Séparateur d'enregistrements     │
                                              │  31 037 1f US   ^_  ::= Séparateurs d'unités             │
                                              └──────────────────────────────────────────────────────────┘
    



    LISTE DES MOTS-CLES

    "3.1.1.11 ENCADREMENT DE CHAINES "...." OU '.....'
    $3.1.1.8 '$' CONTENU D'UNE VARIABLE D'ENVIRONNEMENT
    $#3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $$3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $(cde arg)3.1.1.12 ENCADREMENT DE COMMANDE(S) `cde arg` ou $(cde arg)
    $*3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $-3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $03.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $1 $2 .... $93.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $?3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $?3.3.2.5 exit SORTIE AVEC/SANS CODE RETOUR
    $?3.3.3.3 exit SORTIE AVEC/SANS CODE RETOUR
    $@3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $HOME3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $PATH3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $PS13.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $PS23.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    $TERM3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    ${tableau[indice]}3.2.5 VARIABLES DE TYPE TABLEAU 'tableau[indice]'
    &3.1.1.5 '&' EXECUTION EN ARRIERE PLAN
    &3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    &&3.1.1.3 ';' "&&" "||" CDES EXECUTEES EN SEQUENCE
    &13.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    &23.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    >3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    >&23.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    >>3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    <3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    <&x3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    <<3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    <CTRL><ALT><Fn>1.2 MANIPULATIONS CLAVIER
    <CTRL><x>1.2 MANIPULATIONS CLAVIER
    <TAB>1.2 MANIPULATIONS CLAVIER
    '3.1.1.11 ENCADREMENT DE CHAINES "...." OU '.....'
    ((expr))3.3.3.17 ((expression_arithmetique)) COMMANDE COMPOSEE EXPRESSIONS ARITHMETIQUE/LOGIQUE
    ((expression_arithmetique))3.3.3.17 ((expression_arithmetique)) COMMANDE COMPOSEE EXPRESSIONS ARITHMETIQUE/LOGIQUE
    ()3.1.1.13 '(' et ')' BLOC COMMANDES (cde1 ; .... )
    ()3.1.1.16 nom_fonction () { cde1 ; ....; } FONCTION
    ()3.3.3.18 FONCTIONS SHELL (SOUS-PROGRAMMES)
    () {...}3.1.1.16 nom_fonction () { cde1 ; ....; } FONCTION
    (...)3.1.1.13 '(' et ')' BLOC COMMANDES (cde1 ; .... )
    *3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    /etc/cron.allow5.2 crontab GESTION COMMANDES PERIODIQUES
    /etc/cron.deny5.2 crontab GESTION COMMANDES PERIODIQUES
    /etc/sudoers6.3.1 visudo PARAMETRAGE sudo /etc/sudoers
    /var/cache/man/whatis1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    /var/spool/cron5.2 crontab GESTION COMMANDES PERIODIQUES
    2>3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    :3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    ;3.1.1.3 ';' "&&" "||" CDES EXECUTEES EN SEQUENCE
    ?3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    apropos1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    arguments3.1 EXECUTION COMMANDES
    arguments3.1.3 NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS
    ASCII8.1 TABLE CODE ASCII
    backslash3.1.1.9 CARACTERE '\' ('backslash')
    bash3 SHELL sh bash
    bash2.2.2 STRUCTURE D'UN REPERTOIRE
    bg3.4.4 bg et fg Passage d'arrière en avant plan et réactivation d'une tâche suspendue
    break3.3.3.14 break continue DEBRANCHEMENT/BOUCLE
    break3.3.3.13 until ... do ... done BOUCLE UNTIL
    case3.3.3.8 case . in . esac EXECUTION CONDITIONNELLE
    cd3.3.2.1 cd CHANGEMENT REPERTOIRE DE TRAVAIL
    cd3.3.2 COMMANDES INTERNES DU SHELL
    cd 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    chmod5.1 chmod MODIFICATION DE DROITS D'UN FICHIER
    chmod5 COMMANDES UTILES
    chmod5.1 chmod MODIFICATION DE DROITS D'UN FICHIER
    code ascii8.1 TABLE CODE ASCII
    COMMANDE COMPOSEE ((expr))3.3.3.17 ((expression_arithmetique)) COMMANDE COMPOSEE EXPRESSIONS ARITHMETIQUE/LOGIQUE
    commandes3.1 EXECUTION COMMANDES
    commandes3.1.3 NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS
    commandes3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    comparaisons3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    continue3.3.3.14 break continue DEBRANCHEMENT/BOUCLE
    copier/coller1.1 MANIPULATIONS SOURIS
    crontab5.2 crontab GESTION COMMANDES PERIODIQUES
    crontab5.1.1 BITS SPECIFIQUES DE 'chmod'
    declare3.2 VARIABLES D'ENVIRONNEMENT
    declare3.2.5 VARIABLES DE TYPE TABLEAU 'tableau[indice]'
    declare3.3.2.2 declare,typeset DECLARATION EXPLICITE DE VARIABLES
    df2 SYSTEMES DE FICHIERS SOUS LINUX
    do3.3.3.11 for ... in ... do ... done BOUCLE 'FOR'
    do3.3.3.12 while ... do ... done BOUCLE 'WHILE'
    do3.3.3.13 until ... do ... done BOUCLE UNTIL
    done3.3.3.11 for ... in ... do ... done BOUCLE 'FOR'
    done3.3.3.12 while ... do ... done BOUCLE 'WHILE'
    done3.3.3.13 until ... do ... done BOUCLE UNTIL
    E.R.3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    echo3.3.2.3 echo AFFICHAGE MOTS/TEXTE
    echo3.3.2.2 declare,typeset DECLARATION EXPLICITE DE VARIABLES
    echo 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    elif3.3.3.7 if,then,else,elif,fi INSTRUCTION CONDITIONNELLE
    else3.3.3.7 if,then,else,elif,fi INSTRUCTION CONDITIONNELLE
    env3.2 VARIABLES D'ENVIRONNEMENT
    environnement SHELL3.3.2.9 set ENVIRONNEMENT SHELL
    esac3.3.3.8 case . in . esac EXECUTION CONDITIONNELLE
    eval3.1.1.8 '$' CONTENU D'UNE VARIABLE D'ENVIRONNEMENT
    eval3.3.2.4 eval EVALUATION LIGNE DE COMMANDE+EXECUTION
    eval3.3.2.3 echo AFFICHAGE MOTS/TEXTE
    eval 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    exec3.3.3.6 exec EXECUTION COMMANDE/PROCESSUS COURANT
    exec3.3.3.5 trap MASQUAGE DE SIGNAUX
    exec 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    exit3.3.2.5 exit SORTIE AVEC/SANS CODE RETOUR
    exit3.3.3.3 exit SORTIE AVEC/SANS CODE RETOUR
    exit3.3.2.4 eval EVALUATION LIGNE DE COMMANDE+EXECUTION
    exit3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    exit 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    export3.3.2.2 declare,typeset DECLARATION EXPLICITE DE VARIABLES
    export3.3.2.6 export EXPORTATION VARIABLE ENVIRONNEMENT
    export3.3.2.5 exit SORTIE AVEC/SANS CODE RETOUR
    export 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    expr3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    expr3.3.3.15 true false FONCTIONS LOGIQUES
    expr EXPRESSIONS ARITHMETIQUE/LOGIQUE3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    expression conditionnelle3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    expression régulière1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    expression régulière3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    false3.3.3.15 true false FONCTIONS LOGIQUES
    fg3.4.4 bg et fg Passage d'arrière en avant plan et réactivation d'une tâche suspendue
    fi3.3.3.7 if,then,else,elif,fi INSTRUCTION CONDITIONNELLE
    fichier2.2 TYPES DE FICHIERS LINUX
    file-system2.1 PARTITIONS DISQUE / FILE-SYSTEM
    find5.3 find RECHERCHE DANS UNE ARBORESCENCE
    find5.2 crontab GESTION COMMANDES PERIODIQUES
    fonction3.1.1.16 nom_fonction () { cde1 ; ....; } FONCTION
    fonction3.3.3.18 FONCTIONS SHELL (SOUS-PROGRAMMES)
    for3.3.3.11 for ... in ... do ... done BOUCLE 'FOR'
    getopts3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    getopts3.3.3.1 shift DECALAGE DES ARGUMENTS D'APPEL
    getopts 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    hash 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    history3.3.2.7 history HISTORIQUE DES COMMANDES
    HOME3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    I-node2.2 TYPES DE FICHIERS LINUX
    I-node2.2.1 STRUCTURE D'UN 'I-NODE' 'ext2'
    I-node2.2.2 STRUCTURE D'UN REPERTOIRE
    if3.3.3.7 if,then,else,elif,fi INSTRUCTION CONDITIONNELLE
    in3.3.3.8 case . in . esac EXECUTION CONDITIONNELLE
    in3.3.3.11 for ... in ... do ... done BOUCLE 'FOR'
    indice3.2.5 VARIABLES DE TYPE TABLEAU 'tableau[indice]'
    jobs3.4.3 jobs Affichage des tâches et de leur état
    joker3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    l bit5.1.1 BITS SPECIFIQUES DE 'chmod'
    less1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    login 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    ls5.4 ls AFFICHAGE CONTENU D'UN REPERTOIRE
    ls5.4.1 EXEMPLES D'UTILISATION DE 'ls'
    ls5.1 chmod MODIFICATION DE DROITS D'UN FICHIER
    ls5.3.2 NOMS DE FICHIERS INHABITUELS
    makewhatis1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    man1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    man1.3.1 AIDE EN LIGNE LINUX DE BASE
    MANIPULATIONS CLAVIER1.2 MANIPULATIONS CLAVIER
    MANIPULATIONS SOURIS1.1 MANIPULATIONS SOURIS
    META-CARACTERES3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    mount2.1 PARTITIONS DISQUE / FILE-SYSTEM
    méta-caractères3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    newgrp 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    nom fichier2.2 TYPES DE FICHIERS LINUX
    normes standard3.1.3 NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS
    normes standard3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    options3.1 EXECUTION COMMANDES
    options3.1.3 NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS
    options3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    options du SHELL3.3.1.1 EXECUTION D'UN SCRIPT / APPEL D'UN SHELL
    opérateurs sur des entiers3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    opérateurs sur des noms de fichier3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    opérations arithmétiques3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    PATH3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    pipe3.1.1.7 '|' COMMUNICATION PROCESSUS PAR PIPE
    PS13.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    PS23.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    pwd3.3.2.8 pwd NOM DU REPERTOIRE COURANT
    pwd3.3.2.7 history HISTORIQUE DES COMMANDES
    pwd 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    read3.3.3.4 read SAISIE D'INFORMATION
    read3.3.3.3 exit SORTIE AVEC/SANS CODE RETOUR
    read 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    readonly3.2.1.1 PROTECTION DE MODIFICATION DE VARIABLE
    readonly 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    REDIRECTION3.1.1.6 '<' '>' '>>' '<<' CARACT. REDIRECTION E/S
    return3.3.3.18 FONCTIONS SHELL (SOUS-PROGRAMMES)
    répertoire2.2.2 STRUCTURE D'UN REPERTOIRE
    s bit5.1.1 BITS SPECIFIQUES DE 'chmod'
    section1.3.1 AIDE EN LIGNE LINUX DE BASE
    set3.2 VARIABLES D'ENVIRONNEMENT
    set3.3.2.9 set ENVIRONNEMENT SHELL
    set3.3.2.8 pwd NOM DU REPERTOIRE COURANT
    set 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    Set Group ID5.1.1 BITS SPECIFIQUES DE 'chmod'
    Set User ID5.1.1 BITS SPECIFIQUES DE 'chmod'
    sh3 SHELL sh bash
    sh3.3.1.1 EXECUTION D'UN SCRIPT / APPEL D'UN SHELL
    sh2.2.2 STRUCTURE D'UN REPERTOIRE
    shell3 SHELL sh bash
    shift3.3.3.1 shift DECALAGE DES ARGUMENTS D'APPEL
    shift3.3.3 INSTRUCTIONS DE PROGRAMMATION
    shift 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    SIGABRT3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGALRM3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGBUS3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGEMT3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGFPE3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGILL3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGINT3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGKILL3.3.3.5 trap MASQUAGE DE SIGNAUX
    signal3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGPIPE3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGQUIT3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGSEGV3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGSYS3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGTERM3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGTRAP3.3.3.5 trap MASQUAGE DE SIGNAUX
    SIGUP3.3.3.5 trap MASQUAGE DE SIGNAUX
    sort5.4.1 EXEMPLES D'UTILISATION DE 'ls'
    stat5.1 chmod MODIFICATION DE DROITS D'UN FICHIER
    sticky bit5.1.1 BITS SPECIFIQUES DE 'chmod'
    su6.1 COMMANDES su et sudo
    su6.2 su EXEC. D'UN SHELL/D'UNE CDE SOUS UNE AUTRE ID.
    su6 SECURITE SOUS SHELL
    su6.1 COMMANDES su et sudo
    substr3.1.1.15 ${...}' REMPLACEMENT PARAMETRES
    sudo6.1 COMMANDES su et sudo
    sudo6.3 sudo EXEC. D'UNE CDE/D'UN SHELL SOUS UNE AUTRE ID.
    sudo6 SECURITE SOUS SHELL
    sudo6.2 su EXEC. D'UN SHELL/D'UNE CDE SOUS UNE AUTRE ID.
    syntaxe3.3.3.2 getopts ANALYSE DES OPTIONS D'UNE COMMANDE
    syntaxe commande3.1.3 NORMES STANDARD COMMANDES/OPTIONS/ARGUMENTS
    t bit5.1.1 BITS SPECIFIQUES DE 'chmod'
    tableau3.2.5 VARIABLES DE TYPE TABLEAU 'tableau[indice]'
    tableau[indice]3.2.5 VARIABLES DE TYPE TABLEAU 'tableau[indice]'
    TERM3.2.6 VARIABLES STANDARD (PRE-DEFINIES)
    test3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    test3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    test 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    test -x ...3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    then3.3.3.7 if,then,else,elif,fi INSTRUCTION CONDITIONNELLE
    times 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    trap3.3.3.5 trap MASQUAGE DE SIGNAUX
    trap3.3.3.4 read SAISIE D'INFORMATION
    trap 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    true3.3.3.15 true false FONCTIONS LOGIQUES
    type 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    typeset3.3.2.2 declare,typeset DECLARATION EXPLICITE DE VARIABLES
    ulimit 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    umask 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    unset 3.2 VARIABLES D'ENVIRONNEMENT
    unset 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    until3.3.3.13 until ... do ... done BOUCLE UNTIL
    VARIABLE D'ENVIRONNEMENT3.2 VARIABLES D'ENVIRONNEMENT
    vedit4.1 vi EDITEUR PLEINE PAGE BASE SUR 'ex'
    vi4.1 vi EDITEUR PLEINE PAGE BASE SUR 'ex'
    vi4.1.2 EXEMPLES D'UTILISATION DE 'vi'
    vi4 EDITEURS SOUS UNIX
    view4.1 vi EDITEUR PLEINE PAGE BASE SUR 'ex'
    visudo6.3.1 visudo PARAMETRAGE sudo /etc/sudoers
    visudo6.3 sudo EXEC. D'UNE CDE/D'UN SHELL SOUS UNE AUTRE ID.
    wait 3.3.4 RECAPITULATIF COMMANDES INTERNES DU SHELL
    whatis1.3.1.1 man AFFICHAGE DOCUMENTATION COMMANDE
    while3.3.3.12 while ... do ... done BOUCLE 'WHILE'
    [!...]3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    [!]3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    [...]3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    [...]3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    [expr.cond]3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    [[ expression_conditionnelle ]]3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    [[...]]3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    [[expr.cond]]3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    [[]]3.3.3.10 [[ expression_conditionnelle ]] TEST FICHIER OU CHAINES
    []3.1.1.10 '*', '?', '[]' META-CARACTERES NOMS FICHIERS
    []3.3.3.9 test -x ... TEST FICHIER OU CHAINES
    \3.1.1.9 CARACTERE '\' ('backslash')
    \03.1.1.9 CARACTERE '\' ('backslash')
    \b3.1.1.9 CARACTERE '\' ('backslash')
    \c3.1.1.9 CARACTERE '\' ('backslash')
    \f3.1.1.9 CARACTERE '\' ('backslash')
    \n3.1.1.9 CARACTERE '\' ('backslash')
    \r3.1.1.9 CARACTERE '\' ('backslash')
    \t3.1.1.9 CARACTERE '\' ('backslash')
    \v3.1.1.9 CARACTERE '\' ('backslash')
    \\3.1.1.9 CARACTERE '\' ('backslash')
    `3.1.1.12 ENCADREMENT DE COMMANDE(S) `cde arg` ou $(cde arg)
    {3.1.1.8 '$' CONTENU D'UNE VARIABLE D'ENVIRONNEMENT
    {3.1.1.14 '{' et '}' EXPANSION DES ACCOLADES { arguments }
    {3.1.1.15 ${...}' REMPLACEMENT PARAMETRES
    {3.2 VARIABLES D'ENVIRONNEMENT
    {3.2.3 AFFECTATION CONDITIONNELLE
    {3.2.4 SUBSTITUTION CONDITIONNELLE
    { arguments }3.1.1.14 '{' et '}' EXPANSION DES ACCOLADES { arguments }
    {}3.1.1.14 '{' et '}' EXPANSION DES ACCOLADES { arguments }
    {}3.1.1.15 ${...}' REMPLACEMENT PARAMETRES
    {}3.2 VARIABLES D'ENVIRONNEMENT
    {}3.2.3 AFFECTATION CONDITIONNELLE
    {}3.2.4 SUBSTITUTION CONDITIONNELLE
    |3.1.1.7 '|' COMMUNICATION PROCESSUS PAR PIPE
    |3.3.3.16 expr EXPRESSIONS ARITHMETIQUE/LOGIQUE
    ||3.1.1.3 ';' "&&" "||" CDES EXECUTEES EN SEQUENCE
    }3.1.1.8 '$' CONTENU D'UNE VARIABLE D'ENVIRONNEMENT
    }3.1.1.14 '{' et '}' EXPANSION DES ACCOLADES { arguments }
    }3.1.1.15 ${...}' REMPLACEMENT PARAMETRES
    }3.2 VARIABLES D'ENVIRONNEMENT
    }3.2.3 AFFECTATION CONDITIONNELLE
    }3.2.4 SUBSTITUTION CONDITIONNELLE
    ~3.1.1.4 '~' Expansion du tilde



    Ce document est distribué selon les termes de la licence G.P.L. Documentation. Vous êtes autorisés à le diffuser sur tout support de votre choix, à le publier sur un site internet ou intranet, à la condition que l'auteur original soit mentionné, ce afin d'assurer un meilleur suivi des mises à jour de ce document.

    Auteur: Patrick MARION <pmarion19@free.fr>


    Valid HTML 4.01 Transitional

    Ce site est listé dans la catégorie Formation en informatique : Formations Linux de l'annuaire Produits de Google et Les actualités du Dicodunet