Saída direta de um comando para um arquivo incluindo o comando original E print in terminal

8

Ao executar alguns testes, preciso executar uma série de comandos. Seria extremamente útil para mim, e me pouparia muito tempo, se houvesse uma maneira de fazer todas essas coisas:

  • Execute o comando que preciso executar
  • Redirecionar toda a saída do comando para um arquivo especificado
  • Inclua o comando original no arquivo especificado
  • Imprima a saída do comando original no terminal

As pessoas sugeriram usar o tee para mim, que faz um ótimo trabalho de impressão no terminal, bem como enviar para um arquivo, mas não inclui o comando original. O que eu gostaria de finalizar é um arquivo onde a primeira linha é o comando que eu rodei, e então abaixo está a saída do comando.

Alguém sugeriu isso:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Mas isso não imprime a saída no terminal ou inclui o comando original no arquivo.

Eu aprecio todas as ideias.

    
por shaneoh 28.11.2017 / 10:13

3 respostas

13

Isso é tee que você está pesquisando.

ls -l | tee outfile

imprime a saída de ls -l para stdout (ou seja, o terminal) e salva no arquivo outfile ao mesmo tempo. Mas : Não escreve o nome do comando nem para stdout nem para o arquivo. Para isso, apenas echo do nome do comando antes de executar o comando e canalizar ambas as saídas para tee :

( echo "ls -l" && ls -l ) | tee outfile

É complicado digitar, então por que não definir uma função?

both(){ ( echo "" &&  ) | tee outfile ;}

Depois disso, você pode simplesmente executar

both "ls -l"

para obter o resultado desejado. Coloque a função em seu ~/.bashrc para defini-la em cada novo terminal. Substitua outfile por para poder especificar o arquivo de saída com, por exemplo, both "ls -l" output em vez de gravar em outfile todas as vezes. Se você não quiser que o arquivo de saída seja sobrescrito, mas sim anexá-lo, adicione a opção -a a tee .

    
por dessert 28.11.2017 / 10:30
8

Você pode usar o comando script , que fará com que um arquivo datilografado de tudo seja impresso no seu terminal. Ele cria uma bifurcação e grava tudo até que a shell seja encerrada.

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Então, se eu cat my_output obtiver a mesma saída:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC
    
por AJefferiss 28.11.2017 / 10:49
5

Você pode usar a função de depuração do shell junto com tee :

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... ) inicia um sub-shell que permite “coletar” os fluxos de saída de todos os comandos executados dentro do sub-shell. Ele também contém o efeito do comando set abaixo para este sub-shell.

  • set -x ativa a opção x shell que imprime todos os comandos que o shell executa no fluxo de erros padrão antes de executá-los.

  • 2>&1 redireciona o fluxo 2 (erro padrão) para o fluxo 1 (saída padrão).

  • | redireciona o fluxo de saída padrão do comando esquerdo para o fluxo de entrada padrão do comando à direita.

  • tee FILE copia o fluxo de entrada padrão para o arquivo FILE e para a saída padrão.

Se sua sequência de comandos já estiver em um arquivo de script, faria mais sentido executá-la assim:

bash -x /path/to/script args... 2>&1 | tee output.log
    
por David Foerster 28.11.2017 / 13:53