Aguarde a conclusão do fluxo de stdout e, em seguida, adicione seu conteúdo a um arquivo [duplicado]

8
    

Esta pergunta já tem uma resposta aqui:

    

Estou tentando executar um comando no bash em que tenho um command 1 que aceita uma grande quantidade de conteúdo por meio de stdin e, em seguida, envia esse conteúdo para um file.txt , no entanto, command 1 gera um fluxo de conteúdo e aparentemente file.txt é criado assim que command 1 é iniciado e, em seguida, é atualizado quando command 1 termina com a saída correta.

echo 'a lot of content' | command 1 > file.txt

O problema é que eu só quero criar ou tocar em file.txt once command 1 está completamente terminado.

Existe alguma maneira de conseguir isso?

Editar:

Caso de uso: estou usando um servidor de desenvolvimento da web que é atualizado toda vez que um arquivo é alterado, por isso estou fazendo um pré-processamento antes de realmente atualizar o arquivo.

O problema com o comando acima é que se o arquivo for atualizado ou criado com conteúdo vazio o servidor é atualizado instantaneamente, tendo uma página vazia, então eu realmente queria esperar que o pós-processamento fosse concluído (digamos que demora cerca de 4 segundos) e só então toque em file.txt para que seja corretamente renderizado na página.

Portanto, só há um comando que preciso executar aqui, que é command 1 e, depois que file.txt for atualizado, meu servidor de desenvolvimento web será atualizado automaticamente.

    
por zanona 03.04.2016 / 14:33

2 respostas

15

A solução mais simples é provavelmente sponge como @heemayl sugerido . Alternativamente, você poderia fazer algo assim:

command > tmpfile && mv tmpfile watched_file

Isso fará com que command salve sua saída em tmpfile , que só será renomeada para watched_file (o arquivo que seu servidor está configurado para assistir) assim que o comando sair e somente se tiver saído com sucesso . Para também renomeá-lo em caso de falha, use:

command > tmpfile; mv tmpfile watched_file
    
por 03.04.2016 / 14:50
15

Use sponge do GNU moreutils :

echo 'a lot of content' | command 1 | sponge file.txt

Ou use um arquivo temporário.

    
por 03.04.2016 / 14:35