Canaux et redirections

Table des matières

  1. Principes
  2. Redirections
    1. Sortie standard: sdtout
    2. Sortie d’erreur standard: sdterr
    3. Entrée standard: sdtin
    4. Le Pipe
  3. Canaux
    1. Création de canaux
    2. Redirection de canaux
  4. Device /dev/null
  5. Script shell
  6. Exemples
  7. Sources

Principes

L’exécution d’une commande shell va créer un processus qui ouvrira trois flux correspondants à trois canaux (ou file descriptors):

  • Le canal 0 est l’entrée standard stdin dans lequel le processus va lire les données.
    Par défaut stdin correspond au clavier.
  • Le canal 1 est la sortie standard stdout dans lequel le processus va écrire les données.
    Par défaut stdout correspond à l’écran.
  • Le canal 2 est la sortie d’erreur standard stderr dans lequel le processus va écrire les messages d’erreur.
    Par défaut stderr correspond à l’écran.

Il est possible de modifier le fonctionnement par défaut et de rediriger les différents flux d’entrées/sorties afin que le processus interagisse avec un autre flux.

En outre, en plus des trois canaux par défaut, sept autres canaux, numérotés de 3 à 9, peuvent être ouvert en entrée ou en sortie selon les besoins. Ce qui ramène le nombre total de canaux utilisables simultanément et en parallèle à dix.

Redirections

Sortie standard: sdtout

L’opérateur de redirection > redirige la sortie standard stdout (canal 1), qui est l’écran par défaut, vers un fichier. Si ce dernier n’existe pas un nouveau fichier est alors créé, sinon il est écrasé.

Ceci peut être gênant dans le cas où le contenu du fichier doit être conservé. Dans cette situation, l’utilisation de l’opérateur de redirection >> est privilégié. Avec cet opérateur, si le fichier n’existe pas un nouveau est créé, sinon les données sont ajoutées à la fin du fichier.

Syntaxe:
command > /path/to/some/file
command >> /path/to/some/file
  • > ou 1> redirige la sortie standard stdout dans le fichier list.txt
    $ ls > list.txt
    ou
    $ ls 1> list.txt
  • >> ou 1>> redirige la sortie standard stdout en mode ajout dans le fichier list.txt
    $ ls >> list.txt
    ou
    $ ls 1>> list.txt

Sortie d’erreur standard: sdterr

La redirection de la sortie d’erreur standard stderr (canal 2) est régie par les mêmes règles que la redirection de la sortie standard stdout à la différence que le numéro de canal doit être mentionné avant l’opérateur de redirection > ou >>.

Syntaxe:
command 2> /path/to/some/file
command 2>> /path/to/some/file
  • 2> redirige la sortie d’erreur stderr dans le fichier error.log
    $ bad_command 2> error.log
  • 2>> redirige la sortie d’erreur stderr en mode ajout dans le fichier error.log
    $ bad_command 2>> error.log

Entrée standard: sdtin

La redirection de l’entrée standard stdin (canal 0), par défaut le clavier, est moins courante que la redirection des sorties. Néanmoins, utilisée à bon escient, elle peut être d’une grande utilité. Pour interagir avec les flux d’entrée, deux oprateurs sont disponibles.

L’opérateur < permet d’utiliser des données provenant d’un fichier au lieu du clavier.

L’opérateur << token, également appelé heredoc, lit l’entrée standard jusqu’à la première occurence de mot clef "token". Par défaut, les variables et commandes entre backticks (`) sont évaluées et les caractères spéciaux devront être verrouillés par des backslash (\). Ceci peut-être évité en mettant le mot clef de l’opérateur entre apostrophes (') ou entre guillemets (").

Syntaxe:
command < /path/to/some/file
command << token Contenu a rediriger token
command << "token" Contenu a rediriger token
  • < redirige le fichier inputFile.txt dans l’entrée standard stdin
    $ cat < inputFile.txt
  • << EOF lit l’entrée standard jusqu’à la deuxième occurence du mot clef EOF et redirige le contenu dans l’entrée standard stdin
    $ cat << EOF
    > Line 1 sans verrou sur le $dollars
    > Line 2 avec verrou sur le \$dollars
    > Line 3 repertoire courant $PWD
    > EOF
    Line 1 sans verrou sur le
    Line 2 avec verrou sur le $dollars
    Line 3 repertoire courant /home/user
    $
  • << "EOF" lit l’entrée standard jusqu’à la deuxième occurence du mot clef EOF et redirige le contenu dans l’entrée standard stdin sans interpréter les variables
    $ cat << "EOF"
    > Line 1 sans verrou sur le $dollars
    > Line 2 avec verrou sur le \$dollars
    > Line 3 repertoire courant $PWD
    > EOF
    Line 1 sans verrou sur le $dollars
    Line 2 avec verrou sur le \$dollars
    Line 3 repertoire courant $PWD
    $

Le Pipe

La redirection entre processus avec le pipe (|) permet de créer des “pipelines”, c’est à dire qu’une ligne de commande est constituée d’une succession de commandes dont la sortie de chacune est redirigée dans l’entrée de la suivante.

Contrairement aux autres opérateurs de redirection, le pipe ne passe pas par un fichier mais utilise une mémoire tampon (buffer)

Syntaxe:
command_1 | command_2
command_1 | command_2 | command_3 | ... | command_N
  • Redirige la sortie standard stdout de la commande ls dans l’entrée standard stdin de la commande less
    $ ls | less
  • Liste les fichiers de répertoire courant, les trie par ordre décroissant (du plus gros au plus petit) puis affiche les 5 premier résultats
    $ ls -al | sort -r -n -k 5 | head -5

Canaux

Création de canaux

En plus des trois canaux standard, sept autres canaux, numérotés de 3 à 9, peuvent être créés en entrée ou en sortie. La commande exec permet d’affecter un canal jusqu’à sa fermeture (exec num_canal<&-).

Syntaxe:
exec num_canal> fichier
exec num_canal< fichier
exec num_canal<&-
  • Affecte au canal 3 le fichier d’entrée input.txt. Les commandes pourront dès lors utiliser ce canal comme entrée standard stdin
    $ exec 3< input.txt
  • Affecte au canal 4 le fichier de sortie file.txt. Dorénavant toute écriture dans le fichier file.txt pourra ce faire par le biais de ce canal
    $ exec 4> file.txt
  • Redirige la sortie standard stdout vers le canal 4, soit finalement vers le fichier file.txt
    $ ls >&4
    ou
    $ ls 1>&4
  • Libère le canal 4
    $ exec 4<&-

Redirection de canaux

On peut envisager, dans le cadre de certains traitements, de rediriger un canal dans un autre. Cela permet de regrouper des informations provenant de plusieurs flux distincts dans un seul et unique flux.

  • &> redirige la sortie standard stdout ainsi que la sortie d’erreur standard stderr dans le fichier execution.log
    $ not_so_bad_command &> execution.log
  • >&2 redirige la sortie standard stdout vers la sortie d’erreur standard stderr
    $ ls >&2
  • n&>m redirige tout ce qui est écrit sur le canal n vers le canal m. De ce fait, 2&>1 redirige la sortie d’erreur standard stderr vers la sortie standard stdout
    $ bad_command 2>&1
  • > crée le fichier list.txt à l’intérieur duquel sera inscrit le résultat de la redirection de la sortie d’erreur standard stderr vers la sortie standard stdout
    $ ls > list.txt 2>&1
    Note

    L’ordre d’utilisation des redirections est important.

    La commande suivante ajoute “Bonjour” au fichier hello.txt

    $ echo "Bonjour" 2> hello.txt 1>&2

    alors que la commande suivante affiche “Bonjour” sur stdout.

    $ echo "Bonjour" 1>&2 2> hello.txt
  • 5&<0 crée le canal 5 qui est une copie du canal 0 (stdin)
    $ exec 5&<0

Device /dev/null

/dev/null est un périphérique (device) spécial qui rejette toutes les données qui lui sont transmises. Toute redirection de données dans ce périphérique ne seront pas affichées à l’écran et seront définitivement perdues. Pour cette raison, il est souvent appelé “trou noir”.

Syntaxe:
command > /dev/null
  • Redirige l’entrée standard stdout dans /dev/null
    $ cat file.txt > /dev/null
  • Redirige l’erreur standard stderr dans /dev/null
    $ cat file.txt 2> /dev/null
  • Redirige l’erreur standard stderr dans la sortie standard stdout puis redirige cette sortie combinée dans /dev/null
    $ cat file.txt > /dev/null 2>&1

Script shell

Dans un script shell, il est également possible de rediriger les sorties dans un fichier par le truchement de la commande exec.

L’exemple qui suit illustre l’utilisation d’un script pour rediriger tous les flux dans le fichier /home/user/logs/execution_[date].log

#!/bin/bash
# Redirecting stdin and stdout using 'exec'

dest=/home/user/logs
fname=`date +execution_%d%m%Y_%H%M.log`

exec 1>$dest/$fname 2>&1

# search all occurences of 'Sample' in '.txt' files
find -name '*.txt' | xargs grep 'Sample'

Exemples

  • Récupération et analyse des logs générés lors d’un update cvs en ridirigeant le sdterr vers le sdtin
    $ cvs up 2>&1 | grep --color '^U\|^P\|^A\|^R\|^M\|^C\|^?'
  • Effectue un update cvs et ridirige le flux sdterr dans /dev/null. Ici, l’exécution de la commande grep n’est utile que pour colorer le résultat. Ce dernier sera d’ailleurs identique à l’exemple précédent.
    $ cvs up 2> /dev/null | grep --color '^U\|^P\|^A\|^R\|^M\|^C\|^?'
  • Suppression de fichiers dans une archive
    $ find -type f -printf "zip -d %p META-INF/BadKey.DSA META-INF/BadKey.SF\n" | bash

Sources

This entry was posted in Bash, Development, GNU/Linux and tagged , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.

Leave a Reply

Your email address will not be published. Required fields are marked *