EDITAR
Por favor, veja não apenas a resposta aceita, mas também a(s) outra(s).
Pergunta
Por que redirecionar STDOUT e STDERR para o mesmo arquivo não funciona, embora pareça o mesmo que 1>[FILENAME] 2>&1 ?
Aqui está um exemplo:
perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>a.txt
cat a.txt
# outputs '1' only.
Bem por que? Eu pensei que isso funciona porque... STDOUT é redirecionado para a.txt e STDERR também. O que aconteceu com STDERR?
Com
1>a.txt 2>&1
, o descritor de arquivo #1 é duplicado para #2. Ambos fazem referência ao mesmo "arquivo aberto" e ambos compartilham a posição atual e o modo r/w. (Na verdade, não há nenhuma diferença entre usar 2>&1 e 2<&1.)Com
1>a.txt 2>a.txt
, ambos os descritores de arquivo são abertos independentemente e possuem posições de cursor separadas. (O arquivo também é truncado duas vezes.) Se você escrever "Hello" para fd #1, sua posição será avançada para o byte 5, mas fd #2 permanecerá no byte 0. Imprimir para fd #2 apenas substituirá os dados começando em 0 .Isso é fácil de ver se a segunda gravação for mais curta:
Observe que o Perl possui buffer interno, portanto, neste exemplo, um flush() explícito é necessário para garantir que os dados do fd #1 sejam gravados antes dos dados do fd #2. Caso contrário, os fluxos seriam liberados em ordem imprevisível na saída.
Para comparação, se os descritores de arquivo forem compartilhados, as gravações apenas seguem umas às outras:
Ambos os redirecionamentos truncam o arquivo, portanto, o segundo (em ordem cronológica de execução) substituirá o primeiro. Tentar
Ou apenas use o mesmo descritor de arquivo