Shell Redirections
Shell Redirections
Chaque processus UNIX/Linux a au moins trois descripteurs de fichiers ouverts par défaut :
FD | Nom | Utilisation par le processus | Destination par défaut |
---|---|---|---|
0 | stdin | read() | Entrée standard (clavier) |
1 | stdout | write() | Sortie standard (écran) |
2 | stderr | write() | Erreur standard (écran) |
Un file descriptor (fd) = un pointeur vers un fichier.
Shell Redirections
Afficher les fd du shell courant :
$ ls -l /proc/$$/fd
total 0 lrwx------ 1 tadlos tadlos 64 8 mai 15:30 0 -> /dev/pts/0 lrwx------ 1 tadlos tadlos 64 8 mai 15:30 1 -> /dev/pts/0 lrwx------ 1 tadlos tadlos 64 8 mai 15:30 2 -> /dev/pts/0 lrwx------ 1 tadlos tadlos 64 8 mai 15:30 255 -> /dev/pts/0
/dev/pts/0 étant un fichier spécial représentant une session de terminal.
Shell Redirections
On utilise toujours le signe & devant un descripteur de fichiers, à droite du symbole de redirection.
Dans la syntaxe n>&m
où n et m sont des file descriptors,
si n n'est pas spécifié, c'est le file descriptor 1 (stdout) qui est pris en compte par défaut.
Shell Redirections
Ce n'est pas un lien dynamique.
Le shell copie ce vers quoi pointe actuellement fd1 et assigne cette même cible à fd2.
Shell Redirections
# redirige stdout vers le fichier /tmp/out
ps aux > /tmp/out
# redirige stderr vers le fichier /tmp/err
ps aux 2> /tmp/err
# redirige stderr vers stdout
ps aux 2>&1
S'il y en a plusieurs, les redirections s'exécutent de gauche à droite.
Shell Redirections
Exemple d'un programme program.sh qui redirige la chaîne out dans stdout et redirige la chaîne err dans stderr
$ cat program.sh
#!/bin/bash
# stdout et stderr sont rattachés au tty /dev/pts/0
echo "out" # redirige "out" vers stdout
echo "err" >&2 # redirige "err" vers stderr
$ ./program.sh
out
err
$ ./program.sh >/dev/null # stdout est redirigé vers /dev/null
err
$ ./program.Sh 2>/dev/null # stderr est redirigé vers /dev/null
out
Shell Redirections
$ cat program.sh
#!/bin/bash
echo "out"
echo "err" >&2
Comment faire pour rediriger stdout et stderr dans le même fichier out.err.
Shell Redirections
$ ./program.sh 2>&1 > out.err
État initial : Les file descriptors du shell sont initialement rattachés au terminal de la session en cours (e.g./dev/pts/0).
Shell Redirections
$ ./program.sh 2>&1 > out.err
Rappel : Les redirections se font de gauche à droite.
Étape 1 :
stderr ("fd2") est rattaché à stdout("fd1"), qui était lui-même rattaché au terminal (/dev/pts/0)
Donc "err" est envoyé sur le terminal
Shell Redirections
$ ./program.sh 2>&1 > out.err
Étape 2 : stdout ("fd1") est rattaché au fichier out.err
Shell Redirections
Donc, comment rediriger stdout et stderr dans le même fichier ?
Il faut bien choisir le sens :
$ ./program.sh > out.err 2>&1
Shell Redirections
$ ./program.sh > out.err 2>&1
Étape 1 :
Shell Redirections
$ ./program.sh > out.err 2>&1
Étape 2 :
Shell Redirections
équivalent de : > [file] 2>&1
./program.sh >& out.err
./program.sh &> out.err
C'est sémantiquement équivalent à ./program.sh > out.err 2>&1
Permet de rediriger à la fois stdout et stderr sans se tromper.
Shell Redirections
équivalent de : > [file] 2>&1
La première forme (&>file) est recommandée.
En effet, la forme >&file est ambigüe car :
When using the second form, [file] may not expand to a number or ‘-’.
If it does, other redirection operators apply (see Duplicating File Descriptors) for compatibility reasons.
Shell Redirections
Shell Redirections
Le pipe permet de connecter la sortie standard (stdout) du processus de gauche avec l'entrée standard (stdin) du processus de droite.
[command] | [command2]
Connecte stdout du process command
au stdin du process command2
Pour cela, le shell utilise les appels système pipe2 et dup2 (ou dup3).
Shell Redirections
Tout ce qui est écrit dans pipefd[1] peut être lu depuis pipefd[0].
Shell Redirections
Ensuite, l'appel système dup2() est utilisé (ou dup3).
Il permet de dupliquer le descripteur oldfd sur newfd.
C'est-à-dire que le nouveau descripteur (newfd) pointe sur la même ressource que l'ancien descripteur (olfd).
Shell Redirections
echo "Tadlos" | grep "t"
État initial
Shell Redirections
echo "Tadlos" | grep "t"
pipe2() va créer 2 descripteurs de fichiers : pipe([3, 4])
pipfd[0] = fd3
pipfd[1] = fd4
Shell Redirections
echo "Tadlos" | grep "t"
dup2() va dupliquer fd1 du process lié à echo sur fd4 lié au pipe
dup2(4, 1)
Shell Redirections
echo "Tadlos" | grep "t"
Pareil avec fd0 lié au process grep sur fd3 lié au pipe.
dup2(3, 0)
Shell Redirections
Shell Redirections
Shell Redirections
unknowncommand 2>&1 >/tmp/out | grep –o "unknowncommand"
Le pipe est prioritaire aux redirections.
Shell Redirections
D'abord, la connexion avec le pipe est prioritaire et faite en premier.
Shell Redirections
Ensuite, la première redirection tout à gauche est appliquée.
stderr pointe sur stdout, qui pointe lui-même sur l'extrémité d'écriture du pipe (fd4).
Shell Redirections
Puis, la redirection suivante est appliquée.
stdout pointe sur le fichier /tmp/out.
Shell Redirections
La commande echo est exécutée, ce qui provoque l'envoi d'une erreur "unknowncommand: commande introuvable" sur stderr connecté au pipe.
Shell Redirections
Enfin, la commande grep reçoit en entrée (stdin) le flux d'erreur via l'extrémité de lecture du pipe (fd3).
L'option -o de grep affiche uniquement la chaîne recherchée dans la ligne.
Shell Redirections
Shell Redirections
équivalent de : [command] 2>&1 |[command2]
Permet de rediriger et la sortie standard et la sortie d'erreur dans le pipe.
Shell Redirections
Shell Redirections
Attention, cette syntaxe change la règle des priorités.
Dans ce cas, le pipe n'est plus prioritaire.
Shell Redirections
Contact: tadlos.nayr@proton.me