BASH: escreve a saída de um comando em um arquivo

1

Eu executo um programa de tempo multible usando um script bash, e eu quero que sua saída seja escrita em um arquivo. No entanto, não consegui fazer com que o operador "> filename.txt" funcionasse ... Aqui está o meu script:

for i in {1..10000000..10000}
do
    time ./merge $i>nn
done

alguém pode me ajudar?

Atualização:

A resposta é:

{ time ./merge $i ; } 2>> time.txt
    
por Jim Blum 27.06.2014 / 11:18

4 respostas

3

time é um pouco engraçado. É um Bash embutido, então a primeira coisa que você precisa fazer é limitá-lo ao comando certo. Você pode fazer isso agrupando-o com chaves ou subshelling com parênteses.

Em seguida, você precisa observar que ele é enviado para STDERR . Isso não será redirecionado por padrão, mas podemos corrigir isso redirecionando STDERR para STDOUT e redirecionando isso.

Finalmente (como choroba antes de mim) usando > irá substituir por padrão. Fazê-lo em um loop resultará apenas na última iteração exibida no arquivo. Você quer >> que será anexado.

{ time ./merge $i ; } >> nn 2>&1

Se você não quiser nenhum original STDOUT e quiser apenas a saída de tempo, poderá executar isso:

{ time ./merge $i >/dev/null 2>&1; } 2>> nn

Isso está eliminando toda a saída do comando ./merge e está apenas redirecionando o STDERR do bloco maior.

Assim como um teste para mostrar esse trabalho:

$ for i in {1..10}; do { time echo $i >/dev/null 2>&1; } 2>> nn ; done
$ wc -l nn
40 nn

São blocos de tempo de 10 x 4 linhas (a saída de eco é suprimida).

    
por Oli 27.06.2014 / 11:27
1

Você está sobrescrevendo o arquivo em todas as iterações do loop. Ou redirecionar todo o loop para o arquivo

for i in {1..10000000..10000}
do
    time ./merge $i
done > nn

ou use append:

for i in {1..10000000..10000}
do
    time ./merge $i >> nn
done
    
por choroba 27.06.2014 / 11:28
1

time imprime seus resultados para um erro padrão, não para uma saída padrão. Portanto, você precisa redirecionar a primeira com 2> em vez da última com > . Seu próximo problema é que você está capturando a saída de ./merge e não de time . Portanto, você precisa agrupar os comandos time e ./merge e, em seguida, redirecionar a saída deles . Isso pode ser feito executando-os em um subshell separado ou agrupando-os no shell atual:

  1. Executar em um subshell separado

    for i in {1..10000000..10000}
    do
      ( time ./merge $i ) 2>> nn
    done
    
  2. Executar no mesmo shell

    for i in {1..10000000..10000}
    do
      { time ./merge $i; } 2>> nn
    done
    

Neste caso particular, não há diferença prática entre as duas abordagens.

    
por terdon 27.06.2014 / 13:52
1

O tempo intrínseco bash não é o mesmo que / usr / bin / time. Este último permitirá que você anexe a um arquivo:

/usr/bin/time --append --outout=outputfile command
    
por Jack 29.05.2017 / 22:08