Alguns truques sobre redirecionamento
Alguma particularidade de sintaxe sobre isso pode ter comportamentos importantes. Há algumas amostras pouco sobre redirecionamentos, STDERR
, STDOUT
, e os argumentos ordenação .
1 - Substituindo ou acrescentando?
Redirecionamento>
médio do símbolo .
>
significa enviar para o arquivo completo como um todo , substituindo o destino, se existir (consulte o noclobber
recurso bash no nº 3 mais tarde).
>>
significa enviar além de acrescentaria ao destino, se existir.
De qualquer forma, o arquivo seria criado se não existir.
2 - A linha de comando do shell depende da ordem !!
Para testar isso, precisamos de um comando simples que envie algo nas duas saídas :
$ 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
(Esperando que você não tenha um diretório chamado /tnt
, é claro;). Bem, nós temos !!
Então, vamos ver:
$ 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
A última linha de comando despeja STDERR
no console e parece não ser o comportamento esperado ... Mas ...
Se você deseja fazer alguma pós-filtragem sobre uma saída, a outra ou ambas:
$ 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 --->
Observe que a última linha de comando deste parágrafo é exatamente igual à do parágrafo anterior, onde escrevi parece não ser o comportamento esperado (portanto, esse pode até ser um comportamento esperado).
Bem, existem alguns truques sobre redirecionamentos, para
realizar operações diferentes nas duas saídas :
$ ( 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: o &9
descritor ocorreria espontaneamente por causa de ) 9>&2
.
Adendo: nota! Com a nova versão dobater( >4.0
) há um novo recurso e uma sintaxe mais sexy para fazer esse tipo de coisa:
$ 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, finalmente, para uma formatação de saída em 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
Adendo: nota! A mesma nova sintaxe, nos dois sentidos:
$ 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
Onde STDOUT
passar por um filtro específico, STDERR
para outro e finalmente as duas saídas mescladas passam por um terceiro filtro de comando.
3 - Uma palavra sobre noclobber
opção e >|
sintaxe
É sobre substituição :
Embora set -o noclobber
instrua o bash a não substituir nenhum arquivo existente, a >|
sintaxe permite passar por esta limitação:
$ 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
O arquivo é substituído a cada vez, agora:
$ 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
Passe com >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Desativando esta opção e / ou perguntando se já estiver definido.
$ 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 - Último truque e mais ...
Para redirecionar as duas saídas de um determinado comando, vemos que uma sintaxe correta pode ser:
$ ls -ld /tmp /tnt >/dev/null 2>&1
para este caso especial , há uma sintaxe de atalho: &>
... ou>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota: se 2>&1
existir, também 1>&2
é uma sintaxe correta:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Agora, vou deixar você pensar em:
$ 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 você estiver interessado em mais informações
Você pode ler o manual fino pressionando:
man -Len -Pless\ +/^REDIRECTION bash
em um bater console ;-)