Quelques astuces sur la redirection
Certaines particularités de syntaxe à ce sujet peuvent avoir des comportements importants. Il y a quelques petits échantillons sur les redirections, STDERR
, STDOUT
et arguments commande .
1 - Écraser ou ajouter?
Symbole >
signifie redirection .
>
signifie envoyer dans un fichier complet , écraser la cible si elle existe (voir la noclobber
fonction bash au n ° 3 plus tard).
>>
signifie envoyer en plus de s'ajouterait à la cible s'il existe.
Dans tous les cas, le fichier serait créé s'il n'existait pas.
2 - La ligne de commande du shell dépend de l'ordre !!
Pour tester cela, nous avons besoin d' 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'ayez pas de répertoire nommé /tnt
, bien sûr;). Eh bien, nous l'avons !!
Voyons donc:
$ 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 se décharge STDERR
sur la console, et cela ne semble pas être le comportement attendu ... Mais ...
Si vous souhaitez effectuer un post-filtrage sur une sortie, l'autre 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 --->
Notez que la dernière ligne de commande de ce paragraphe est exactement la même que dans le paragraphe précédent, où j'ai écrit ne semble pas être le comportement attendu (donc, cela pourrait même être un comportement attendu).
Eh bien, il y a quelques astuces sur les redirections, pour
effectuer différentes opérations 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: le &9
descripteur se produirait spontanément à cause de ) 9>&2
.
Addendum: nota! Avec la nouvelle version defrapper( >4.0
) il y a 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
passer par un filtre spécifique, STDERR
à un autre et enfin les deux sorties fusionnées passent par un troisième filtre de commande.
3 - Un mot sur l' noclobber
option et la >|
syntaxe
Il s'agit d' écraser :
Tout en set -o noclobber
demandant à bash de ne pas écraser de fichier existant, la >|
syntaxe vous permet de passer par cette limitation:
$ 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, enfin 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
Passer 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à définie.
$ 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 - Dernière astuce et plus ...
Pour rediriger les deux sorties d'une commande donnée, nous voyons qu'une bonne syntaxe pourrait être:
$ ls -ld /tmp /tnt >/dev/null 2>&1
pour ce cas particulier , il existe une syntaxe de raccourci: &>
... ou>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota: si elle 2>&1
existe, 1>&2
est une syntaxe correcte aussi:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Maintenant, je vais vous laisser réfléchir sur:
$ 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 souhaitez plus d' informations
Vous pouvez lire le bon manuel en cliquant sur:
man -Len -Pless\ +/^REDIRECTION bash
dans un frapper console ;-)