Quelques astuces sur la redirection
Une certaine particularité syntaxique à ce sujet peut avoir des comportements importants. Il y a quelques petits échantillons sur les redirections, STDERR
, STDOUT
et des arguments commander .
1 - Écraser ou annexer ?
Symbole >
signifie redirection .
-
>
signifie envoyer à un fichier complet en écrasant la cible si elle existe (voir noclobber
fonction bash à #3 plus tard).
-
>>
signifie envoyer en plus de s'ajoutera à la cible si elle existe.
Dans tous les cas, le fichier sera créé s'il n'existe pas.
2 - Le ligne de commande shell
Pour tester cela, nous avons besoin de une commande simple qui enverra quelque chose sur les deux sorties :
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
(En supposant que vous n'avez pas un répertoire nommé /tnt
bien sûr ;). Eh bien, nous l'avons !
Alors, voyons voir :
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
La dernière ligne de commande vide STDERR
à la console, et il semble que ce ne soit pas le comportement attendu... Mais...
Si vous voulez en faire post-filtrage à propos de standard sortie, erreur ou les deux :
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
Remarquez que la dernière ligne de commande dans ce paragraphe est exactement la même que dans le paragraphe précédent, où j'ai écrit ne semblent pas être le comportement attendu (donc, cela pourrait même être un comportement attendu).
Eh bien, il y a un petit truc à propos des redirections, pour faire une opération différente sur les deux sorties :
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
Nota : &9
descripteur se produirait spontanément en raison de ) 9>&2
.
Addendum : nota ! Avec la nouvelle version de bash ( >4.0
), il existe une nouvelle fonctionnalité et une syntaxe plus sexy pour faire ce genre de choses :
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
Et enfin pour un tel formatage de sortie en cascade :
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Addendum : nota ! Même nouvelle syntaxe, dans les deux sens :
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Où STDOUT
passent par un filtre spécifique, STDERR
vers un autre et enfin les deux sorties fusionnées passent par un troisième filtre de commande.
2b - Utilisation |&
au lieu de
Syntaxe command |& ...
pourrait être utilisé comme un alias para command 2>&1 | ...
. Les mêmes règles concernant l'ordre des lignes de commande s'appliquent. Plus de détails à Quelle est la signification de l'opérateur |& en bash ?
3 - Un mot sur noclobber
et l'option >|
syntaxe
C'est à peu près écrasement :
Alors que set -o noclobber
demander à bash de no écraser tout fichier existant, le >|
La syntaxe vous permet de franchir cette limite :
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
Le fichier est écrasé à chaque fois, et bien maintenant :
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
Passez à travers avec >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Désactiver cette option et/ou demander si elle est déjà activée.
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4 - Dernier tour et plus...
Pour rediriger les deux la sortie d'une commande donnée, nous voyons qu'une syntaxe correcte pourrait être :
$ ls -ld /tmp /tnt >/dev/null 2>&1
pour cette spécial Dans ce cas, il existe une syntaxe raccourcie : &>
... ou >&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota : si 2>&1
existent, 1>&2
est également une syntaxe correcte :
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Maintenant, je vais vous laisser réfléchir :
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- Si vous êtes intéressé par más information
Vous pouvez lire le manuel détaillé en cliquant ici :
man -Len -Pless\ +/^REDIRECTION bash
dans un bash console ;-)
61 votes
@dbr Je ne pense pas que ce soit seulement bash - je crois que c'est un truc de bourne shell ; d'où sh, bash, ksh, ash, dash, etc.
8 votes
Ceci fait partie du paragraphe de redirection décrivant les shells compatibles POSIX, ou shell POSIX en abrégé. ksh est un shell POSIX par exemple. Voir : pubs.opengroup.org/onlinepubs/009695399/utilités/
15 votes
Cette construction fonctionne également sous Windows.
7 votes
C'est généralement mieux de faire
2>&1
que 2>/dev/null ;-)15 votes
J'ai pensé que je devais mentionner que
|&
est un raccourci pour2>&1 |
si vous utilisez zsh. Je ne peux pas dire si cela s'applique aux autres shells de type bourne ou si c'est une fonctionnalité propre à zsh.3 votes
@chrixian
|&
est également dans Bash, une grande fonctionnalité. Mais il semble que ce ne soit pas POSIX ( ?)2 votes
Vous pouvez vérifier cette réponse stackoverflow.com/questions/10508843/what-is-dev-null-21/