Vous êtes ici :
Accueil Cours Administration Système La programmation Système avec Shell Les redirections élémentaires

La programmation Système avec Shell : Les redirections élémentaires

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.  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.

 

Les 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
 

Exemple :  

$ pwd
/home/tony
$ pwd > fich
$
   => aucun résultat affiché à l’écran !

$ cat fich  => le résultat a été enregistré dans le fichier fich
/home/tony
$
 
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.  
 

 

Exemple : 

$ >f    => crée ou remet à zéro le fichier f  
$   
$ ls -l f
-rw-r--r--   1 tony  users 0 oct 26 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.
 

Exemple : 

$  > f1  ;  >f2
$

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

Exemple : 

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
$ 

 
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
 

Exemple :  

$ pwd > t
$  
$ date >> t
$  
$ cat  t

/home/tony
lundi 26 octobre 2015, 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 >.
 

 

Exemple :  

$ pwd
/home/tony
$ 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
 

Exemple : 

$ 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'est-à-dire 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.
 

Exemple : 

$ 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'est-à-dire également vers le fichier trace [b].
 
La syntaxe  &> fichier  est équivalente à la syntaxe   > fichier  2>&1
 
Exemple : 

$ ls vi err  &> trace   
$  
$ cat trace

ls: vi: Aucun fichier ou répertoire de ce type
err
$  
 
Attention : Les redirections étant traitées de gauche à droite, l’ordre des redirections est important.
 

-  Redirection de l'entrée standard :   <  fichier
 
Exemple : 

$  mail  tony  < lettre
$

 
La commande mail envoie à l’utilisateur tony 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.
 

Exemple : 

$ cat fic_noms
alain dupont
veronique laguepe
$  
$ liste=$(<fic_noms)
$  
$ echo $liste
    => liste est une variable et non un fichier !
alain dupont veronique laguepe  => 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.

 

Exemple : 

$ 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 :
  
  
Exemple : 

$   < 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.

 

Exemple : 

$ cat fic  =>  cat ouvre le fichier fic afin de lire son contenu
bonjour
et au revoir
$
$ cat  <fic
  =>  cat lit son entrée standard (redirigée par le shell)
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.
 

Exemple : 

$ 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.

 

Exemple : 

$ nblignes=$( wc -l < fic_noms )
$
$ echo  $nblignes
3  
=>  nombre de lignes
$
 
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.
 
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.  
 
Exemple : 

$ 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>&-  
 
Exemple : 

$ >&-   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.
 

 

Les  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 :
 
Exemple : 

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. Un résultat équivalent aurait pu être obtenu d’une manière moins élégante en exécutant la suite de commandes :
 
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 : cmd1 | cmd2 |... |  cmdn
 
Chaque commande est exécutée par un processus distinct, la sortie standard de la commande   cmdi-1 étant connectée à l’entrée standard de la commande cmdi .
 

Exemple : 

$ 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.

 


 




Vous êtes ici :
Accueil Cours Administration Système La programmation Système avec Shell Les redirections élémentaires