Como redirecionar a saída do comando time para um arquivo no Linux?

202

Apenas uma pequena pergunta sobre programas de temporização no Linux: o comando time permite medir o tempo de execução de um programa:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

O que funciona bem. Mas se eu tentar redirecionar a saída para um arquivo, ela falhará.

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

Eu sei que existem outras implementações de tempo com a opção -o para escrever um arquivo, mas minha pergunta é sobre o comando sem essas opções.

Alguma sugestão ?

ed82
fonte
3
Possível duplicação do tempo de execução da gravação do script bash em um arquivo , e não estou convencido de que essa seja a primeira pergunta desse tipo.
Jonathan Leffler
1
Esta é uma duplicata do stackoverflow.com/questions/2408981/…
codeforester

Respostas:

266

Experimentar

{ time sleep 1 ; } 2> time.txt

que combina o STDERR de "time" e seu comando em time.txt

Ou use

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

que coloca STDERR de "sleep" no arquivo "sleep.stderr" e apenas STDERR de "time" entra em "time.txt"

janeiro
fonte
2
Obrigado, isso responde exatamente a minha pergunta. Se entendi corretamente, o resultado do comando time pode ser obtido no stderr?
ED82
7
Sim, mas você deve colocá-lo entre colchetes, caso contrário, o redirecionamento fará parte do comando que timeavalia.
janeiro
5
@ Daniel Você sempre pode redirecionar a saída do comando interno separadamente (por exemplo, {time sleep 1 2> sleepStdErr.txt;} 2> time.txt) e isso forneceria apenas a saída de tempo. Não tenho certeza se existe uma maneira de obtê-lo de forma independente.
precisa saber é o seguinte
10
Se você deseja usar o tempo com algo como grep que lê fora de stdout, tente { time sleep 1; } 2>&1 | grep real. Isso envia stderr para stdout, que o grep pode ler.
clayzermk1
9
NÃO esqueça o ';' personagem antes de fechamento '}', não vai funcionar sem (eu fiz, e ... maravilha porque não está funcionando :))
THESorcerer
38

Quebra automática timee o comando que você está cronometrando em um conjunto de colchetes.

Por exemplo, os seguintes horários lse gravam o resultado lse os resultados do tempo em outfile:

$ (time ls) > outfile 2>&1

Ou, se você deseja separar a saída do comando da saída capturada de time:

$ (time ls) > ls_results 2> time_results
sampson-chen
fonte
12
Não é necessário introduzir um subshell aqui.
janeiro
1
@ sampson-chen Isso só funciona porque o ls não escreve nada no stderr certo? Como você "separaria" a saída de 'time' da saída do comando a ser executado se o comando gravar em stdout e stderr?
David Doria
36

Simples. O GNUtime utilitário tem uma opção para isso.

Mas você precisa garantir que está não usando builtin do seu shell timede comando, pelo menos, o bashbuiltin não fornece essa opção! É por isso que você precisa fornecer o caminho completo do timeutilitário:

/usr/bin/time -o time.txt sleep 1
cmaster - restabelece monica
fonte
Você também pode usar o não
interno
14

Se você se importa com a saída de erro do comando, pode separá-los dessa maneira enquanto ainda usa o comando de tempo interno.

{ time your_command 2> command.err ; } 2> time.log

ou

{ time your_command 2>1 ; } 2> time.log

Como você vê, os erros do comando vão para um arquivo (já que stderré usado para time).

Infelizmente, você não pode enviá-lo para outro identificador (como 3>&2), pois isso não existirá mais fora do{...}

Dito isto, se você pode usar o tempo GNU, faça o que Tim Ludwinski disse.

\time -o time.log command
Marca
fonte
8

Como a saída do comando 'time' é uma saída de erro, redirecione-a para que a saída padrão seja mais intuitiva para processar ainda mais.

{ time sleep 1; } 2>&1 |  cat > time.txt
jaycee xu
fonte
6

Se você estiver usando o tempo GNU em vez do bash embutido, tente

time -o outfile command

(Nota: A hora do GNU formata um pouco diferente do que o bash embutido).

Tim Ludwinski
fonte
1
Obrigado. E você pode usar \time -o outfile command(com ``) para uso GNU em vez de construído dentro.
Mark
3
&>out time command >/dev/null

no seu caso

&>out time sleep 1 >/dev/null

então

cat out
alinsoar
fonte
3
Idéia elegante, mas leva o shell a não usar seu comando interno. Se você não possui um timebinário real instalado, outele conterá algo como bash: time: command not found.
Scy
Além disso, o formato para o horário GNU não é o mesmo que o bash embutido, causando problemas para a análise automática.
Guss
3

Acabei usando:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Onde "a" é anexado
  • Onde "o" é seguido pelo nome do arquivo para anexar a
  • Onde "f" é um formato com uma sintaxe semelhante a printf
  • Onde "% E" produz 0:00:00; horas: minutos: segundos
  • Eu tive que chamar / usr / bin / time porque o "time" do bash estava atropelando e não tinha as mesmas opções
  • Eu só estava tentando obter saída para arquivo, não a mesma coisa que OP
Locane
fonte
2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

Isso tem o benefício de não gerar subcascas, e o pipeline final tem seu stderr restaurado no stderr real.

Adam Heath
fonte
0

Se você não quiser tocar no stdout e no stderr do processo original, poderá redirecionar o stderr para o descritor de arquivo 3 e vice-versa:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

Você pode usar isso para um wrapper (por exemplo, cronjobs) para monitorar tempos de execução:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log
Tobias Gödderz
fonte
0

Se você estiver usando, cshpoderá usar:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

Por exemplo:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
Leo Cardona
fonte