Como obter o tempo de execução de um script efetivamente?

259

Gostaria de exibir o tempo de conclusão de um script.

O que eu faço atualmente é -

#!/bin/bash
date  ## echo the date at start
# the script contents
date  ## echo the date at end

Este é apenas o horário de início e fim do script. Seria possível exibir uma saída bem granulada, como tempo / hora do processador, etc?

    
por mtk 19.10.2012 / 15:26

13 respostas

350

Use apenas time quando chamar o script:

time yourscript.sh
    
por 19.10.2012 / 15:28
117

Se time não for uma opção,

start='date +%s'
stuff
end='date +%s'

runtime=$((end-start))
    
por 19.10.2012 / 19:38
61

Basta ligar para times sem argumentos ao sair do script .

Com ksh ou zsh , você também pode usar time . Com zsh , time também lhe dará o tempo de relógio de parede, além do tempo de CPU usuário e sistema .

Para preservar o status de saída do seu script, você pode:

ret=$?; times; exit "$ret"

Ou você também pode adicionar uma armadilha em EXIT :

trap times EXIT

Dessa forma, os horários serão chamados sempre que o shell sair e o status de saída for preservado.

$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
shell  0.67s user 0.01s system 100% cpu 0.677 total
children  0.00s user 0.00s system 0% cpu 0.677 total

Observe também que todos os bash , ksh e zsh têm uma variável especial $SECONDS que conta o número de segundos desde que o shell foi iniciado. Em zsh e ksh93 , essa variável também pode ser feita com ponto flutuante (com typeset -F SECONDS ) para obter mais precisão. Este é apenas o tempo do relógio de parede, não o tempo de CPU.

    
por 19.10.2012 / 15:40
23

Estou um pouco atrasado para o bandwagon, mas queria postar a minha solução (para precisão de sub-segundo) no caso de outros tropeçarem nesta discussão através da pesquisa. A saída está no formato de dias, horas, minutos e finalmente segundos:

res1=$(date +%s.%N)

# do stuff in here

res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)

printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds

Espero que alguém ache isso útil!

    
por 30.08.2013 / 04:12
11

Meu método para bash :

# Reset BASH time counter
SECONDS=0
    # 
    # do stuff
    # 
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
    
por 25.01.2017 / 22:28
4
#!/bin/bash
start=$(date +%s.%N)

# HERE BE CODE

end=$(date +%s.%N)    
runtime=$(python -c "print(${end} - ${start})")

echo "Runtime was $runtime"

Sim, isso chama o Python, mas se você puder conviver com isso, isso é uma solução muito boa e concisa.

    
por 23.06.2014 / 15:52
4

Essa pergunta é bem antiga, mas, ao tentar encontrar minha maneira favorita de fazer isso, essa discussão surgiu ... e estou surpreso que ninguém mencionou:

perf stat -r 10 -B sleep 1

'perf' é uma ferramenta de análise de desempenho incluída no kernel em 'tools / perf' e frequentemente disponível para instalação como um pacote separado ('perf' no CentOS e 'linux-tools' no Debian / Ubuntu). O Linux Kernal perf Wiki tem muito mais informações sobre isso.

A execução de 'perf stat' fornece alguns detalhes, incluindo o tempo médio de execução no final:

1.002248382 seconds time elapsed                   ( +-  0.01% )
    
por 24.12.2017 / 06:51
3

Aqui está uma variação da resposta de Alex. Eu só me importo com minutos e segundos, mas eu também queria formatado de forma diferente. Então eu fiz isso:

start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
    
por 17.07.2014 / 01:10
3
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M [email protected]
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."
    
por 15.01.2016 / 05:00
3

Uma pequena função de shell que pode ser adicionada antes dos comandos para medir seu tempo:

tm() {
  s=$(date +%s)
  $@
  rc=$?
  echo "took $[$(date +%s)-$s] seconds. return code $rc" >&2
  return $rc
}

Em seguida, use-o no seu script ou na linha de comando da seguinte forma:

tm the_original_command with all its parameters
    
por 05.04.2017 / 22:41
2

Usando o somente bash, também é possível medir e calcular o tempo de duração de uma parte do script de shell (ou o tempo decorrido para todo o script):

start=$SECONDS

... # do time consuming stuff

end=$SECONDS

agora você pode imprimir a diferença:

echo "duration: $((end-start)) seconds."

se você só precisa de duração incremental, faça:

echo "duration: $((SECONDS-start)) seconds elapsed.."

Você também pode armazenar a duração em uma variável:

let diff=end-start
    
por 07.06.2017 / 10:57
1
#!/bin/bash
begin=$(date +"%s")

Script

termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
    
por 22.11.2014 / 08:40
0

Pessoalmente, gosto de incluir todo o meu código de script em alguma função "principal" da seguinte forma:

main () {
 echo running ...
}

# stuff ...

# calling the function at the very end of the script
time main

Observe como é fácil usar o comando time neste cenário. Obviamente, você não está medindo o tempo exato, incluindo o tempo de análise do script, mas acho que é preciso o suficiente na maioria das situações.

    
por 10.08.2018 / 15:59