IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Introduction à la programmation en Bash


précédentsommairesuivant

V. Redirections élémentaires

V-1. Descripteurs de fichiers

Un processus Unix possède par défaut trois voies d’interaction avec l’extérieur appelées entrées / sorties standard identifiées par un entier positif ou nul appelé descripteur de fichier.
Ces entrées / sorties standard sont :

  • une entrée standard , de descripteur 0
  • une sortie standard , de descripteur 1
  • une sortie standard pour les messages d’erreurs, de descripteur 2.

Toute commande étant exécutée par un processus, nous dirons également qu’une commande possède trois entrées / sorties standard.

 
Sélectionnez
0  --> commande   --> 1
          |
          v
          2

De manière générale, une commande de type filtre (ex : cat) prend ses données sur son entrée standard qui correspond par défaut au clavier, affiche ses résultats sur sa sortie standard, par défaut l’écran, et affiche les erreurs éventuelles sur sa sortie standard pour les messages d’erreurs, par défaut l’écran également.

V-2. Redirections élémentaires

On peut rediriger séparément chacune des trois entrées/sorties standard d’une commande. Cela signifie qu’une commande pourra :

  • lire les données à traiter à partir d’un fichier et non du clavier de l’utilisateur
  • écrire les résultats ou erreurs dans un fichier et non à l’écran.

Redirection de la sortie standard : > fichier ou 1> fichier

 
Sélectionnez
$ pwd
/home/sanchis
$ pwd > fich
			  => aucun résultat affiché à l’écran !
			  => le résultat a été enregistré dans le fichier fich
$ cat fich
/home/sanchis
$

Cette première forme de redirection de la sortie standard écrase l'ancien contenu du fichier de sortie (fichier fich) si celui-ci existait déjà, sinon le fichier est créé. Le shell prétraite une commande avant de l’exécuter : dans l’exemple ci-dessous, le shell crée un fichier vide f devant recevoir les résultats de la commande (ici inexistante) ; l’unique effet de >f sera donc la création du fichier f ou sa remise à zéro.

 
Sélectionnez
$ >f	         => crée ou remet à zéro le fichier f
$ ls -l f
-rw-r--r--       1 sanchis    users                0 oct 22 11:34 f
$

Une commande ne possède qu’une seule sortie standard; par conséquent, si on désire effacer le contenu de plusieurs fichiers, il est nécessaire d’utiliser autant de commandes que de fichiers à effacer. Le caractère ; permet d’exécuter séquentiellement plusieurs commandes écrites sur la même ligne.

 
Sélectionnez
$   > f1   ;   >f2
$

La redirection de la sortie standard de cat est souvent utilisée pour affecter un contenu succinct à un fichier.

 
Sélectionnez
$ cat >tata                      => l’entrée standard est directement recopiée dans tata
a demain
si vous le voulez bien
^D
$ cat tata
a demain
si vous le voulez bien
$
 
Sélectionnez
			  0            1
a demain              	----->  cat  ------>  tata
si vous le voulez bien

Pour concaténer (c’est à dire ajouter à la fin) la sortie standard d'une commande au contenu d'un fichier, une nouvelle forme de redirection doit être utilisée : >> fichier

 
Sélectionnez
$ pwd > t
$ date >> t
$ cat t
/home/sanchis
lundi 20 novembre 2006, 15:27:41 (UTC+0100)
$

Comme pour la redirection précédente, l’exécution de >> fich crée le fichier fich s’il n’existait pas.

Redirection de la sortie standard pour les messages d'erreur : 2> fichier

On ne doit laisser aucun caractère espace entre le chiffre 2 et le symbole >.

 
Sélectionnez
$ pwd
/home/sanchis
$ ls vi                        => l’éditeur de texte vi se trouve dans le répertoire /usr/bin
ls: vi: Aucun fichier ou répertoire de ce type
$ ls vi 2> /dev/null
$

Le fichier spécial /dev/null est appelé « poubelle » ou « puits » car toute sortie qui y est redirigée, est perdue. En général, il est utilisé lorsqu’on est davantage intéressé par le code de retour de la commande plutôt que par les résultats ou messages d’erreur qu’elle engendre. Comme pour la sortie standard, il est possible de concaténer la sortie standard pour les messages d’erreur d'une commande au contenu d'un fichier : 2>> fichier

 
Sélectionnez
$ ls vi
ls: vi: Aucun fichier ou répertoire de ce type
$ ls vi 2>err
$ ls date 2>>err
$ cat err
ls: vi: Aucun fichier ou répertoire de ce type
ls: date: Aucun fichier ou répertoire de ce type
$

Pour rediriger la sortie standard pour les messages d’erreur vers la sortie standard (c.a.d vers le fichier de descripteur 1), on utilisera la syntaxe : 2>&1 Cela est souvent utilisé lorsqu’on désire conserver dans un même fichier toutes les sorties.

 
Sélectionnez
$ ls
Mail                    err                     public_html           tmp
_.forward               fic_noms                t
$ ls vi err >trace 2>&1
$ cat trace
ls: vi: Aucun fichier ou répertoire de ce type
err
$

La sortie standard est redirigée vers le fichier trace [a] puis la sortie standard pour les messages d’erreur est redirigée vers la sortie standard, c.-à-d. également vers le fichier trace [b].

 
Sélectionnez
                     1
ls vi err      ------------>      Ecran
  2 |                      |
    v                      v
                         trace
                [a]

                     1
ls vi err      ------------>      Ecran
    |                ^     |
  2 |                |     |
    v-----------------     v
                         trace
                [b]

La syntaxe &> fichier est équivalente à la syntaxe > fichier 2>&1

 
Sélectionnez
$ ls vi err &> trace
$ cat trace
ls: vi: Aucun fichier ou répertoire de ce type
err
$

Les redirections étant traitées de gauche à droite, l’ordre des redirections est important.

Exercice : Que fait la commande : ls vi fic_noms 2>&1 >trace

Redirection de l'entrée standard : < fichier

 
Sélectionnez
$    mail    sanchis    < lettre
$

La commande mail envoie à l’utilisateur sanchis le contenu du fichier lettre. Une substitution de commande associée à une redirection de l’entrée standard permet d’affecter à une variable le contenu d’un fichier. En effet, la substitution de commande $(cat fichier) peut être avantageusement remplacée par la syntaxe $(< fichier). Cette deuxième forme est plus rapide.

 
Sélectionnez
$ cat fic_noms
pierre beteille
anne debazac
julie donet
$ liste=$(<fic_noms)
$ echo $liste                                => liste est une variable et non un fichier !
pierre beteille anne debazac julie donet     => elle contient le contenu du fichier fic_noms
$

Redirections séparées des entrées / sorties standard : Les entrées / sorties peuvent être redirigées indépendamment les unes des autres.

 
Sélectionnez
$ wc -l       <fic_noms    >fic_nblignes         2>err
$ cat fic_nblignes
3
$ cat err
$

La commande unix wc -l affiche le nombre de lignes d’un ou plusieurs fichiers texte. Ici, il s’agit du nombre de lignes du fichier fic_noms. Le fichier err est créé mais est vide car aucune erreur ne s’est produite. Dans cet exemple, la disposition des redirections dans la ligne de commande n’a pas d’importance, car les deux sorties ne sont pas redirigées vers le même fichier. Il est possible de placer les redirections où l'on souhaite car le shell traite les redirections avant d'exécuter la commande :

 
Sélectionnez
$    < fic_noms         > fic_nblignes        wc     2>err      -l
$ cat fic_nblignes
3
$ cat err
$

La plupart des commandes affichent leurs résultats sous la même forme, suivant que l’on passe en argument le nom d’un fichier ou que l’on redirige son entrée standard avec ce fichier.

 
Sélectionnez
Ex :                            => cat ouvre le fichier fic afin de lire son contenu
        $ cat fic
        bonjour
        et au revoir
        $
                                => cat lit son entrée standard (redirigée par le shell)
        $ cat <fic
        bonjour
        et au revoir
        $

Il n’en est pas ainsi avec la commande wc : celle-ci n’écrit pas les résultats de la même manière.

 
Sélectionnez
$ wc -l fic_noms
3 fic_noms
$ wc -l < fic_noms
3
$

Par conséquent, lorsque l’on désirera traiter la sortie d’une commande wc, il faudra prendre garde à la forme utilisée. La deuxième forme est préférable lorsque on ne souhaite que le nombre de lignes.

 
Sélectionnez
$ nblignes=$( wc -l < fic_noms )
$ echo $nblignes
3                  => nombre de lignes
$

Texte joint :
Il existe plusieurs syntaxes légèrement différentes pour passer un texte joint comme entrée à une commande. Néanmoins, la syntaxe présentée ci-dessous est la plus simple.

 
Sélectionnez
Syntaxe :       cmd <<mot
                texte
                mot

L’utilisation de cette syntaxe permet d’alimenter l’entrée standard de la commande cmd à l’aide d’un contenu texte délimité par deux balises mot.
Aucun caractère espace ne doit être présent entre << et mot.

 
Sélectionnez
$ a=3.5 b=1.2
$ bc <<EOF
> $a + $b
> EOF
4.7
$

La commande unix bc est une calculatrice utilisable en ligne de commande. Dans l’exemple ci-dessus, deux variables a et b sont initialisées respectivement avec les chaînes de caractères 3.5 et 1.2. Le shell effectue les deux substitutions de variables présentes entre les mots EOF puis alimente l’entrée standard de bc avec le texte obtenu. Cette commande calcule la valeur de l’expression fournie puis affiche son résultat sur sa sortie standard.

Fermeture des entrées / sorties standard :
Fermeture de l’entrée standard : <&-
Fermeture de la sortie standard : >&-
Fermeture de la sortie standard pour les messages d’erreur : 2>&-

 
Sélectionnez
$ >&-     echo coucou
-bash: echo: write error: Mauvais descripteur de fichier
$

Il y a fermeture de la sortie standard puis une tentative d’écriture sur celle-ci : l’erreur est signalée par l’interpréteur de commandes.

V-3. Tubes

Le mécanisme de tube (symbolisé par le caractère |) permet d’enchaîner l’exécution de commandes successives en connectant la sortie standard d’une commande à l’entrée standard de la commande suivante :

 
Sélectionnez
Ex : ls -l /bin |     more

Il y a affichage du contenu du répertoire /bin (commande ls -l /bin) écran par écran (commande more). En effet, les informations affichées par ls -l sont envoyées vers l’entrée de la commande more qui les affiche écran par écran. La sortie standard de la dernière commande n’étant pas redirigée, l’affichage final s’effectue à l’écran.

 
Sélectionnez
              1          0             1
ls -l /bin  ----->  |  ----->  more  ----->
    2|                          2|
     v                           v

Un résultat équivalent aurait pu être obtenu d’une manière moins élégante en exécutant la suite de commandes :

 
Sélectionnez
ls -l      /bin    >temporaire ;       more < temporaire ; rm temporaire

La commande ls -l /bin écrit le résultat dans le fichier temporaire ; ensuite, on affiche écran par écran le contenu de ce fichier ; enfin, on efface ce fichier devenu inutile. Le mécanisme de tube évite à l’utilisateur de gérer ce fichier intermédiaire.

Pipelines :
On appelle pipeline, une suite non vide de commandes connectées par des tubes :

 
Sélectionnez
cmd1 | ... | cmdn

Chaque commande est exécutée par un processus distinct, la sortie standard de la commande cmd_i-1 étant connectée à l’entrée standard de la commande cmd_i .

 
Sélectionnez
$ date | tee trace1 trace2 | wc -l
1	     => date n’écrit ses résultats que sur une seule ligne
$ cat trace1
lundi 20 novembre 2006, 15:37:49 (UTC+0100)
$ cat trace2
lundi 20 novembre 2006, 15:37:49 (UTC+0100)
$

La commande unix tee écrit le contenu de son entrée standard sur sa sortie standard tout en gardant une copie dans le ou les fichiers dont on a passé le nom en argument.
Dans l’exemple ci-dessus, tee écrit le résultat de date dans les fichiers trace1 et trace2 ainsi que sur sa sortie standard, résultat passé à la commande wc -l.


précédentsommairesuivant

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.