Table des matières
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
0est l’entrée standardstdindans lequel le processus va lire les données.
Par défautstdincorrespond au clavier.- Le canal
1est la sortie standardstdoutdans lequel le processus va écrire les données.
Par défautstdoutcorrespond à l’écran.- Le canal
2est la sortie d’erreur standardstderrdans lequel le processus va écrire les messages d’erreur.
Par défautstderrcorrespond à 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/filecommand >> /path/to/some/file
>ou1>redirige la sortie standardstdoutdans le fichierlist.txt$ ls > list.txt ou $ ls 1> list.txt>>ou1>>redirige la sortie standardstdouten mode ajout dans le fichierlist.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/filecommand 2>> /path/to/some/file
2>redirige la sortie d’erreurstderrdans le fichiererror.log$ bad_command 2> error.log2>>redirige la sortie d’erreurstderren mode ajout dans le fichiererror.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/filecommand << token Contenu a rediriger tokencommand << "token" Contenu a rediriger token
<redirige le fichierinputFile.txtdans l’entrée standardstdin$ cat < inputFile.txt<< EOFlit l’entrée standard jusqu’à la deuxième occurence du mot clefEOFet redirige le contenu dans l’entrée standardstdin$ 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 clefEOFet redirige le contenu dans l’entrée standardstdinsans 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_2command_1 | command_2 | command_3 | ... | command_N
- Redirige la sortie standard
stdoutde la commandelsdans l’entrée standardstdinde la commandeless$ 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> fichierexec num_canal< fichierexec num_canal<&-
- Affecte au canal
3le fichier d’entréeinput.txt. Les commandes pourront dès lors utiliser ce canal comme entrée standardstdin$ exec 3< input.txt- Affecte au canal
4le fichier de sortiefile.txt. Dorénavant toute écriture dans le fichierfile.txtpourra ce faire par le biais de ce canal$ exec 4> file.txt- Redirige la sortie standard
stdoutvers le canal4, soit finalement vers le fichierfile.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 standardstdoutainsi que la sortie d’erreur standardstderrdans le fichierexecution.log$ not_so_bad_command &> execution.log>&2redirige la sortie standardstdoutvers la sortie d’erreur standardstderr$ ls >&2n&>mredirige tout ce qui est écrit sur le canalnvers le canalm. De ce fait,2&>1redirige la sortie d’erreur standardstderrvers la sortie standardstdout$ bad_command 2>&1>crée le fichierlist.txtà l’intérieur duquel sera inscrit le résultat de la redirection de la sortie d’erreur standardstderrvers la sortie standardstdout$ ls > list.txt 2>&1
L’ordre d’utilisation des redirections est important.
La commande suivante ajoute “Bonjour” au fichier
hello.txt$ echo "Bonjour" 2> hello.txt 1>&2alors que la commande suivante affiche “Bonjour” sur
stdout.$ echo "Bonjour" 1>&2 2> hello.txt5&<0crée le canal5qui est une copie du canal0(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
stdoutdans/dev/null$ cat file.txt > /dev/null- Redirige l’erreur standard
stderrdans/dev/null$ cat file.txt 2> /dev/null- Redirige l’erreur standard
stderrdans la sortie standardstdoutpuis 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
sdterrvers lesdtin$ cvs up 2>&1 | grep --color '^U\|^P\|^A\|^R\|^M\|^C\|^?' - Effectue un update cvs et ridirige le flux
sdterrdans/dev/null. Ici, l’exécution de la commandegrepn’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