La duplication est vraiment la partie importante ici.
Voyons où vont les descripteurs de fichiers avant la redirection. Il s'agit normalement du terminal actuel, par exemple:
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
Maintenant, si nous appelons ls -lsans redirection, les messages de sortie et d'erreur vont à mon terminal sous /dev/pts/1.
Si nous redirigeons d'abord le STDOUTvers un fichier ( ls -l > dirlist), cela ressemble à ceci:
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
Lorsque nous redirigeons ensuite vers STDERRun doublon du STDOUTdescripteur de fichier ( ls -l > dirlist 2>&1), STDERRva vers un doublon de /home/bon/dirlist:
STDOUT ---> /home/bon/dirlist
STDERR ---> /home/bon/dirlist
Si nous voulions d' abord rediriger STDERRvers un double du STDOUTdescripteur de fichier de ( ls -l 2>&1):
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
et puis STDOUT dans un fichier ( ls -l 2>&1 > dirlist), nous obtiendrions ceci:
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
Ici, STDERRva toujours au terminal.
Vous voyez, l'ordre dans la page de manuel est correct.
Test de la redirection
Maintenant, vous pouvez le tester vous-même. En utilisant ls -l /proc/$$/fd/, vous voyez où STDOUT(avec fd 1) et STDERR(avec fd 2), vont pour le processus actuel:
$ ls -l /proc/$$/fd/
total 0
lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1
Créons un petit script shell qui montre où vos descripteurs de fichiers sont pointés. De cette façon, nous obtenons toujours l'état lors de l'appel ls, y compris toute redirection à partir du shell appelant.
$ cat > lookfd.sh
#!/bin/sh
ls -l /proc/$$/fd/
^D
$ chmod +x lookfd.sh
(Avec CtrlD, vous envoyez une fin de fichier et arrêtez ainsi la catlecture de la commande STDIN.)
Maintenant, appelez ce script avec différentes combinaisons de redirection:
$ ./lookfd.sh
total 0
lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh 2>&1 > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out 2>&1
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh
Vous pouvez voir que les descripteurs de fichiers 1 (pour STDOUT) et 2 (pour STDERR) varient. Pour le plaisir, vous pouvez également rediriger STDINet voir le résultat:
$ ./lookfd.sh < /dev/zero
total 0
lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh
(Question laissée au lecteur: où pointe le descripteur de fichier 255? ;-))