Em um shell Unix, se eu quiser combinar stderr
e stdout
entrar no stdout
fluxo para manipulação adicional, posso acrescentar o seguinte no final do meu comando:
2>&1
Então, se eu quiser usar head
a saída de g++
, posso fazer algo assim:
g++ lots_of_errors 2>&1 | head
para que eu possa ver apenas os primeiros erros.
Eu sempre tenho problemas para lembrar disso, e eu constantemente tenho que procurar, e é principalmente porque eu não entendo completamente a sintaxe desse truque em particular.
Alguém pode acabar com isso e explicar caráter a caráter, o que 2>&1
significa?
2>&1
do que 2> / dev / null ;-)|&
é uma abreviação para2>&1 |
se você estiver usando o zsh. Não sei se isso se aplica a outras conchas do tipo bourne ou se é um recurso exclusivo do zsh.Respostas:
O descritor de arquivo 1 é a saída padrão (
stdout
).O descritor de arquivo 2 é o erro padrão (
stderr
).Aqui está uma maneira de lembrar essa construção (embora não seja totalmente precisa): a princípio,
2>1
pode parecer uma boa maneira de redirecionarstderr
parastdout
. No entanto, ele será realmente interpretado como "redirecionarstderr
para um arquivo chamado1
".&
indica que o que segue é um descritor de arquivo e não um nome de arquivo. Assim, a construção torna-se:2>&1
.fonte
&2>&1
?&
só é interpretado como "descritor de arquivo" no contexto de redirecionamentos. A escritacommand &2>&
é analisada comocommand &
e2>&1
, ou seja, "executecommand
em segundo plano, execute o comando2
e redirecione seu stdout para seu stdout".2>'&1'
redireciona o stdout para
afile.txt
. É o mesmo que fazerPara redirecionar o stderr, você deve:
>&
é a sintaxe para redirecionar um fluxo para outro descritor de arquivo - 0 é stdin, 1 é stdout e 2 é stderr.Você pode redirecionar o stdout para o stderr fazendo o seguinte:
Ou vice-versa:
Portanto, resumindo ...
2>
redireciona o stderr para um arquivo (não especificado), acrescentando o&1
redirecionamento do stderr ao stdout.fonte
java ... 2&1 >> data.log
, eu vi um colega fazer isso?cmd 2>&1 >> somefile.log
anexará stdout / stderr para um arquivo - é basicamente o mesmo que acima, com>> file
a acrescentarcmd 2>&1 >>file
não redireciona o stderr para o arquivo, mascmd >> file 2>&1
sim. Ordem importa. No primeiro caso, stderr é redirecionado para o stdout do shell (possivelmente um tty se o comando for digitado interativamente) e, em seguida, stdout é direcionado para o arquivo. No segundo caso, stdout é direcionado para o arquivo e stderr é direcionado para o mesmo local.0(or 1,2)>&0(or 1,2)
como uma opção para controlar a saída? É oecho test >test.log 2>&1
mesmo queecho test 2>&1 >test.log
?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 onoclobber
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 :
(Esperando que você não tenha um diretório chamado
/tnt
, é claro;). Bem, nós temos !!Então, vamos ver:
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:
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 :
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:E, finalmente, para uma formatação de saída em cascata:
Adendo: nota! A mesma nova sintaxe, nos dois sentidos:
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:O arquivo é substituído a cada vez, agora:
Passe com
>|
:Desativando esta opção e / ou perguntando se já estiver definido.
4 - Último truque e mais ...
Para redirecionar as duas saídas de um determinado comando, vemos que uma sintaxe correta pode ser:
para este caso especial , há uma sintaxe de atalho:
&>
... ou>&
Nota: se
2>&1
existir, também1>&2
é uma sintaxe correta:4b- Agora, vou deixar você pensar em:
4c- Se você estiver interessado em mais informações
Você pode ler o manual fino pressionando:
em um bater console ;-)
fonte
Encontrei este post brilhante sobre redirecionamento: Tudo sobre redirecionamentos
Redirecione a saída padrão e o erro padrão para um arquivo
Essa linha única usa o
&>
operador para redirecionar os fluxos de saída - stdout e stderr - do comando para o arquivo. Este é o atalho do Bash para redirecionar rapidamente os dois fluxos para o mesmo destino.Aqui está como é a tabela do descritor de arquivos após o Bash redirecionar os dois fluxos:
Como você pode ver, stdout e stderr agora apontam para
file
. Portanto, qualquer coisa escrita em stdout e stderr é gravadafile
.Existem várias maneiras de redirecionar os dois fluxos para o mesmo destino. Você pode redirecionar cada fluxo um após o outro:
Essa é uma maneira muito mais comum de redirecionar os dois fluxos para um arquivo. O primeiro stdout é redirecionado para o arquivo e, em seguida, stderr é duplicado para ser o mesmo que stdout. Então, os dois fluxos acabam apontando para
file
.Quando o Bash vê vários redirecionamentos, ele os processa da esquerda para a direita. Vamos seguir as etapas e ver como isso acontece. Antes de executar qualquer comando, a tabela de descritores de arquivos do Bash é assim:
Agora o Bash processa o primeiro arquivo de redirecionamento. Já vimos isso antes e faz stdout apontar para o arquivo:
O próximo Bash vê o segundo redirecionamento 2> & 1. Não vimos esse redirecionamento antes. Este duplica o descritor de arquivo 2 para ser uma cópia do descritor de arquivo 1 e obtemos:
Ambos os fluxos foram redirecionados para o arquivo.
No entanto, tenha cuidado aqui! Escrita
não é o mesmo que escrever:
A ordem dos redirecionamentos é importante no Bash! Este comando redireciona apenas a saída padrão para o arquivo. O stderr ainda será impresso no terminal. Para entender por que isso acontece, vamos seguir as etapas novamente. Portanto, antes de executar o comando, a tabela do descritor de arquivos é semelhante a esta:
Agora o Bash processa os redirecionamentos da esquerda para a direita. Ele vê primeiro 2> & 1 e duplica stderr para stdout. A tabela do descritor de arquivo se torna:
Agora, o Bash vê o segundo redirecionamento
>file
e redireciona o stdout para o arquivo:Você vê o que acontece aqui? Stdout agora aponta para o arquivo, mas o stderr ainda aponta para o terminal! Tudo o que é gravado no stderr ainda é impresso na tela! Portanto, tenha muito, muito cuidado com a ordem dos redirecionamentos!
Observe também que, no Bash, escrever
é exatamente o mesmo que:
fonte
>&
/dev/tty0
?Os números se referem aos descritores de arquivo (fd).
stdin
stdout
stderr
2>&1
redireciona o fd 2 para 1.Isso funciona para qualquer número de descritores de arquivo, se o programa os usar.
Você pode ver
/usr/include/unistd.h
se os esquece:Dito isto, escrevi ferramentas C que usam descritores de arquivo não padrão para log personalizado, para que você não o veja, a menos que o redirecione para um arquivo ou algo assim.
fonte
Essa construção envia o fluxo de erro padrão (
stderr
) para o local atual da saída padrão (stdout
) - esse problema de moeda parece ter sido negligenciado pelas outras respostas.Você pode redirecionar qualquer identificador de saída para outro usando esse método, mas é usado com mais frequência para canalizar
stdout
estderr
transmitir em um único fluxo para processamento.Alguns exemplos são:
Observe que o último não direcionará
stderr
paraoutfile2
- ele o redireciona para o questdout
era quando o argumento foi encontrado (outfile1
) e, em seguida, redirecionastdout
paraoutfile2
.Isso permite alguns truques bastante sofisticados.
fonte
some_program 2>&1 > /dev/null
não funciona assim:some_program > /dev/null 2>&1
.2>&1
é uma construção de shell POSIX. Aqui está um detalhamento, token por token:2
: Descritor de arquivo de saída " Erro padrão ".>&
: Duplique um operador Descritor de Arquivo de Saída (uma variante do operador Redirecionamento de Saída>
). Dado[x]>&[y]
, o descritor de arquivo indicado porx
é feito para ser uma cópia do descritor de arquivo de saíday
.1
" Saída padrão " descritor de arquivo de saída.A expressão
2>&1
copia o descritor de arquivo1
para o local2
, para que qualquer saída gravada em2
("erro padrão") no ambiente de execução vá para o mesmo arquivo originalmente descrito por1
("saída padrão").Mais explicações:
Descritor de arquivo : "Um número inteiro único e não negativo por processo usado para identificar um arquivo aberto para fins de acesso a arquivos".
Saída / erro padrão : Consulte a seguinte nota na seção Redirecionamento da documentação do shell:
fonte
2 é o erro padrão do console.
1 é a saída padrão do console.
Este é o Unix padrão e o Windows também segue o POSIX.
Por exemplo, quando você corre
o erro padrão é redirecionado para a saída padrão, para que você possa ver as duas saídas juntas:
Após a execução, você pode ver toda a saída, incluindo erros, no debug.log.
Em seguida, a saída padrão vai para out.log e o erro padrão para err.log.
Eu sugiro que você tente entender isso.
fonte
perl test.pl > debug.log 2>&1
Para responder sua pergunta: Pega qualquer saída de erro (normalmente enviada ao stderr) e grava-a na saída padrão (stdout).
Isso é útil com, por exemplo, 'more' quando você precisa de paginação para toda a saída. Alguns programas, como imprimir informações de uso no stderr.
Para ajudá-lo a lembrar
"2> & 1" simplesmente aponta tudo enviado para stderr, para stdout.
Também recomendo a leitura deste post sobre o redirecionamento de erro, onde este assunto é abordado em todos os detalhes.
fonte
Do ponto de vista de um programador, significa exatamente isso:
Veja a página do manual .
Entender que
2>&1
é uma cópia também explica por que ...... não é o mesmo que ...
O primeiro enviará os dois fluxos para
file
, enquanto o segundo enviará erros parastdout
e a saída comum parafile
.fonte
Achei isso muito útil se você é iniciante, leia isso
Atualização:
No sistema Linux ou Unix, existem dois locais onde os programas enviam a saída para: Saída padrão (stdout) e Erro padrão (stderr) . Você pode redirecionar essas saídas para qualquer arquivo.
Como se você fizer isso
ls -a > output.txt
Nada será impresso no console. Toda a saída (stdout) é redirecionada para o arquivo de saída.
E se você tentar imprimir o conteúdo de qualquer arquivo que não saia significa que a saída será um erro como se você imprimir test.txt que não estiver presente no diretório atual A
cat test.txt > error.txt
saída será
Mas o arquivo error.txt estará vazio porque redirecionamos o stdout para um arquivo não stderr.
portanto, precisamos do descritor de arquivo (um descritor de arquivo nada mais é que um número inteiro positivo que representa um arquivo aberto. Você pode dizer que o descritor é o ID exclusivo do arquivo) para informar ao shell qual tipo de saída estamos enviando para o arquivo. No sistema Unix / Linux 1 é para stdout e 2 para stderr .
agora, se você fizer isso
ls -a 1> output.txt
, estará enviando a saída padrão (stdout) para o output.txt.e se você fizer isso
cat test.txt 2> error.txt
significa que está enviando erro padrão (stderr) para error.txt.&1
é usado para referenciar o valor do descritor de arquivo 1 (stdout).Agora, o ponto
2>&1
significa "Redirecionar o stderr para o mesmo local em que estamos redirecionando o stdout"Agora você pode fazer isso
cat maybefile.txt > output.txt 2>&1
a saída padrão (stdout) e o erro padrão (stderr) serão redirecionados para output.txt.
Agradecimentos a Ondrej K. por apontar
fonte
Pessoas, lembre-se sempre paxdiablo dica 's sobre a atual localização do alvo redirecionamento ... Ele é importante.
Meu mnemônico pessoal para o
2>&1
operador é este:&
no significado'and'
ou'add'
(o personagem é um ampere - e , não é?)2
(stderr) para onde1
(stdout) já está / atualmente e adicione os dois fluxos' .O mesmo mnemônico também funciona para o outro redirecionamento usado com frequência
1>&2
:&
significadoand
ouadd
... (você entendeu o e comercial, não é?)1
(stdout) para onde2
(stderr) já está / atualmente e adicione os dois fluxos' .E lembre-se sempre: você precisa ler cadeias de redirecionamentos 'do final', da direita para a esquerda ( não da esquerda para a direita).
fonte
Ref:
Digite
/^REDIRECT
para localizar noredirection
seção e saiba mais ...Uma versão online está aqui: 3.6 Redirecionamentos
PS:
Muitas vezes,
man
era a ferramenta poderosa para aprender Linux.fonte
Desde que
/foo
não exista no seu sistema e exista/tmp
…imprimirá o conteúdo
/tmp
e imprimirá uma mensagem de erro para/foo
irá enviar o conteúdo de
/tmp
para/dev/null
e imprimir uma mensagem de erro para/foo
fará exatamente o mesmo (observe o 1 )
imprimirá o conteúdo
/tmp
e enviará a mensagem de erro para/dev/null
enviará a listagem e a mensagem de erro para
/dev/null
é taquigrafia
fonte
É como passar o erro ao stdout ou ao terminal.
Ou seja,
cmd
não é um comando:O erro é enviado para o arquivo assim:
Erro padrão é enviado para o terminal.
fonte
0 para entrada, 1 para stdout e 2 para stderr.
Uma dica :
somecmd >1.txt 2>&1
está correto, enquantosomecmd 2>&1 >1.txt
está totalmente errado, sem efeito!fonte
unix_commands 2>&1
Isso é usado para imprimir erros no terminal.
A seguir, ilustra o processo
&2
"buffer", a partir do qual o fluxo de erros padrão faz2
referência.&1
"buffer", a partir do qual o fluxo de saída padrão faz1
referência.Portanto, pegue o
unix_commands
fluxo de erros padrão2
e redirecione>
o fluxo (de erros) para o endereço da memória de saída padrão&1
, para que eles sejam transmitidos para o terminal e impressos.fonte