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

5.2.1. Redirection de la sortie standard

Syntaxe : > fichier ou 1> fichier

$ pwd
/home/sanchis
$ pwd > fich
$               => aucun résultat affiché à l’écran !
$ cat fich      => le résultat a été enregistré dans le fichier 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.

$ >f     => crée ou remet à zéro le fichier f
$
$ ls -l f
-rw-r--r-- 1 sanchis sanchis 0  8 janv. 20:33 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.

$ > f1 ; >f2
$

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

$ 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

$ pwd > t
$
$ date >> t
$
$ cat t
/home/sanchis
sam. 08 janv. 2022 20:35:47 CET 
$

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

5.2.2. Redirection de la sortie standard pour les messages d'erreur

Syntaxe : 2> fichier

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

$ pwd
/home/sanchis
$ ls vi    => l’éditeur de texte vi se trouve dans le répertoire /usr/bin
ls: impossible d'accéder à vi: Aucun fichier ou dossier 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 [cf. Chapitre 7, Code de retour] de la commande plutôt que par les résultats ou messages d’erreur qu’elle engendre.

Pour écrire un message mess sur la sortie standard pour les messages d’erreur : echo >&2 mess

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

$ ls vi
ls: impossible d'accéder à vi: Aucun fichier ou dossier de ce type
$
$ ls vi 2>err
$
$ ls date 2>>err
$
$ cat err
ls: impossible d'accéder à vi: Aucun fichier ou dossier de ce type
ls: impossible d'accéder à date: Aucun fichier ou dossier 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.

$ ls vi err >trace 2>&1
$
$ cat trace
ls: impossible d'accéder à vi: Aucun fichier ou dossier 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].

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

$ ls vi err &> trace
$
$ cat trace
ls: impossible d'accéder à vi: Aucun fichier ou dossier de ce type
err
$

L’ajout en fin de fichier s’effectue en utilisant la syntaxe &>> fichier

$ ls /etc/passwd date &>> trace
$ 
$ cat trace
ls: impossible d'accéder à vi: Aucun fichier ou dossier de ce type
err
ls: impossible d'accéder à date: Aucun fichier ou dossier de ce type
/etc/passwd
$

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

Pour éviter que le contenu d’un fichier ne soit écrasé lors d’une redirection malheureuse, il est possible d’utiliser l’option noclobber de la commande interne set.

$ cat t
/home/sanchis  
sam. 08 janv. 2022 20:35:47 CET
$ 
$ set -o noclobber	=> activation de l’option noclobber
$ 
$ echo coucou > t
bash: t : impossible d'écraser le fichier existant
$ 
$ ls vi 2>t
bash: t : impossible d'écraser le fichier existant
$ 
$ echo ciao >> t		
$ 				=> la concaténation reste possible
$ cat t
/home/sanchis
sam. 08 janv. 2022 20:35:47 CET
ciao
$
$ set +o noclobber	=> pour désactiver l’option 
$

5.2.3. Redirection de l'entrée standard

Syntaxe : < fichier

$ mail sanchis < lettre
$

La commande unix 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.

$ 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

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.

$ 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), sans savoir 
bonjour			=>	qu’il s’agit du contenu du fichier fic
et au revoir
$

Il n’en est pas ainsi avec la commande unix wc : celle-ci n’écrit pas les résultats de la même manière suivant qu’un argument lui a été fourni ou bien qu’elle lise son entrée standard.

$ 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 unix wc, il faudra prendre garde à la forme utilisée. La deuxième forme est préférable lorsqu’on ne souhaite obtenir que le nombre de lignes.

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

5.2.4. Redirections séparées des entrées / sorties standard

Les entrées / sorties peuvent être redirigées indépendamment les unes des autres.

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

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

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

5.2.5. Texte joint

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


    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 comprenant éventuellement plusieurs lignes et délimité par deux balises mot.

La deuxième balise mot doit impérativement se trouver en début de ligne. Par contre, un ou plusieurs caractères espace ou tabulation peuvent être présents entre << et mot.

$ a=3.5 b=1.2
$
$ bc << EOF
> $a + $b		=> la chaîne ">  " indique que la commande n’est syntaxiquement pas terminée
> 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 puis affiche son résultat sur sa sortie standard.

Lorsque bash détecte qu’une commande n’est pas syntaxiquement terminée, il affiche une chaîne d’appel différente (contenue dans la variable prédéfinie PS2 du shell) matérialisée par un caractère > suivi d’un caractère espace, invitant l’utilisateur à continuer la saisie de sa commande.

5.2.6. Chaîne jointe

Syntaxe : cmd <<< chaîne

C’est une syntaxe plus compacte que le texte joint : le contenu transmis à l’entrée standard de la commande cmd se présente sous la forme d’une chaîne de caractères chaîne.

$ a=1.2  b=-5.3
$
$ bc <<< "$a + $b"
-4.1
$

Le choix d’utiliser un texte joint ou bien une chaîne jointe s’effectue suivant la structure et la longueur du texte à transmettre à la commande cmd.

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

$ >&- echo coucou
bash: echo: erreur d'écriture : 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.