Isto,
paste out sum | awk ... | tee sum
tem uma condição de corrida. paste
abre sum
para lê-lo e tee
abre para escrever, truncando-o. O shell inicia ambos aproximadamente ao mesmo tempo, então é a chance de abrir o arquivo primeiro.
É claro que, na prática, o shell precisa iniciar os utilitários um de cada vez, em alguma ordem específica. Provavelmente faz isso da esquerda para a direita, então paste
pode ter uma chance maior de ser o primeiro, mas esse é um detalhe de implementação e, em qualquer caso, o agendador de SO decide o que é executado quando.
Se paste
for o primeiro, ele abrirá o arquivo com os dados ainda intactos e, provavelmente, terá tempo suficiente para ler os dados também. Se tee
conseguir abrir o arquivo antes que paste
o tenha lido, então paste
verá um arquivo vazio.
Aqui,
paste out sum | awk ... > sum
O shell abre sum
para gravação, truncando-a. Ele pode fazer isso em paralelo ao início de paste
, mas como truncar sum
não envolve iniciar outro utilitário, isso provavelmente acontece primeiro. (Eu não tenho certeza se há uma regra sobre a ordem de processamento de redirecionamentos e iniciar os comandos em um pipeline como este, mas eu não contaria com isso.)
Há uma ferramenta chamada sponge
para corrigir esse problema (e uma dúzia de perguntas sobre ele ). Ele coleta a entrada que recebe e apenas grava após a entrada ser fechada. Isso deve ter sum
atualizado corretamente, sempre:
paste out sum | awk ... | sponge sum