Alcuni trucchi per il reindirizzamento
Alcune particolarità della sintassi al riguardo possono avere comportamenti importanti. Ci sono alcuni piccoli campioni di circa redirezioni, STDERR
, STDOUT
, e gli argomenti ordinazione .
1 - Sovrascrivere o aggiungere?
Simbolo >
significa reindirizzamento .
>
significa inviare a tutto il file completato , sovrascrivendo il target se esiste (vedere la noclobber
funzione bash al # 3 più avanti).
>>
significa invia oltre a aggiungerebbe al target se esiste.
In ogni caso, il file verrebbe creato se non esistesse.
2 - La riga di comando della shell dipende dall'ordine !!
Per provare questo, abbiamo bisogno di un semplice comando che invierà qualcosa su entrambi gli output :
$ 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
(Mi aspettavo di non avere una directory chiamata /tnt
, ovviamente;). Bene, ce l'abbiamo !!
Quindi, vediamo:
$ 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
L'ultima riga di comando esegue STDERR
il dump sulla console e sembra non essere il comportamento previsto ... Ma ...
Se si desidera creare un filtro post su un output, l'altro o entrambi:
$ 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 --->
Si noti che l'ultima riga di comando in questo paragrafo è esattamente la stessa del paragrafo precedente, in cui ho scritto sembra non essere il comportamento previsto (quindi, questo potrebbe anche essere un comportamento previsto).
Bene, ci sono alcuni trucchi sui reindirizzamenti, per
fare diverse operazioni su entrambi gli output :
$ ( 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: il &9
descrittore si presenta spontaneamente a causa di ) 9>&2
.
Addendum: nota! Con la nuova versione dibash( >4.0
) c'è una nuova funzionalità e una sintassi più sexy per fare questo tipo di cose:
$ 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
E infine per una formattazione dell'output così a cascata:
$ ((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! Stessa nuova sintassi, in entrambi i modi:
$ 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
Dove STDOUT
passa attraverso un filtro specifico, STDERR
a un altro e infine entrambi gli output uniti passano attraverso un terzo filtro di comando.
3 - Una parola su noclobber
opzione e >|
sintassi
Si tratta di sovrascrivere :
Mentre set -o noclobber
chiedi a bash di non sovrascrivere alcun file esistente, la >|
sintassi ti consente di superare questa limitazione:
$ 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
Il file viene sovrascritto ogni volta, bene ora:
$ 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
Passa con >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Disattivando questa opzione e / o chiedendo se è già impostato.
$ 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 - Ultimo trucco e altro ...
Per reindirizzare entrambi l' output da un determinato comando, vediamo che una sintassi corretta potrebbe essere:
$ ls -ld /tmp /tnt >/dev/null 2>&1
per questo caso speciale , esiste una sintassi del collegamento: &>
... o>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota: se 2>&1
esiste, 1>&2
è anche una sintassi corretta:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Ora, ti farò pensare a:
$ 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- Se sei interessato a maggiori informazioni
Puoi leggere il manuale eccellente premendo:
man -Len -Pless\ +/^REDIRECTION bash
in un bash console ;-)