Você precisa saber duas coisas:
- Um descritor de arquivos aberto conhecido pelo lado do modo de aplicação de um processo faz referência a um objeto de kernel interno conhecido como descrição do arquivo , que é uma instância de um arquivo aberto . Pode haver várias descrições de arquivo por arquivo e vários descritores de arquivo compartilhando uma descrição de arquivo.
- A posição atual do arquivo é um atributo de uma descrição do arquivo . Portanto, se vários descritores de arquivo forem mapeados para uma única descrição de arquivo, todos eles compartilharão a mesma posição de arquivo atual, e uma alteração na posição do arquivo executada usando um descritor de arquivo afetará todos os outros descritores de arquivo.
Tais alterações são promulgadas por processos que chamam as chamadas de sistema
read()
/readv()
,write()
/writev()
,lseek()
e semelhantes. O comandoecho
chamawrite()
/writev()
, claro.
Então o que acontece é isto:
-
command 1>file.txt 2>&1
cria apenas uma descrição de arquivo, porque o shell só abre um arquivo uma vez. O shell torna ambos a saída padrão e os descritores de arquivo de erro padrão mapeiam para aquela descrição de arquivo único. Ele duplica a saída padrão para o erro padrão. Assim, uma gravação via descritor de arquivo moverá a posição do arquivo atual compartilhado: cada gravação vai após a gravação anterior da descrição do arquivo comum. E como você pode ver os resultados dos comandosecho
não substituem um ao outro. -
command 1>file.txt 2>file.txt
cria duas descrições de arquivo, porque o shell abre o mesmo arquivo duas vezes, em resposta aos dois redirecionamentos explícitos. Os descritores de arquivo de saída padrão e de erro padrão são mapeados para duas descrições de arquivo diferentes, que, por sua vez, são mapeadas para o mesmo arquivo único. As duas descrições de arquivo têm posições de arquivo atuais totalmente independentes, e cada gravação vai imediatamente a gravação anterior na mesma descrição de arquivo. E como você pode ver, o resultado é que o que é escrito via um pode sobrescrever o que está escrito pelo outro, de várias maneiras diferentes, de acordo com a ordem em que você executa as gravações.