Je voudrais afficher l'heure de fin d'un script.
Ce que je fais actuellement, c'est -
#!/bin/bash
date ## echo the date at start
# the script contents
date ## echo the date at end
Cela montre simplement l'heure de début et de fin du script. Serait-il possible d'afficher une sortie à grain fin comme le temps processeur/temps io, etc.?
Utilisez simplement time
lorsque vous appelez le script:
time yourscript.sh
Si time
n'est pas une option,
start=`date +%s`
stuff
end=`date +%s`
runtime=$((end-start))
Appelez simplement times
sans arguments à la sortie de votre script.
Avec ksh
ou zsh
, vous pouvez également utiliser time
à la place. Avec zsh
, time
vous donnera également l'heure de l'horloge murale en plus de l'utilisateur et système temps CPU.
Pour conserver le statut de sortie de votre script, vous pouvez le faire:
ret=$?; times; exit "$ret"
Ou vous pouvez également ajouter un piège sur EXIT
:
trap times EXIT
De cette façon, les heures seront appelées à chaque sortie du shell et le statut de sortie sera préservé.
$ 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
Notez également que tous les bash
, ksh
et zsh
ont un $SECONDS
variable spéciale qui est automatiquement incrémentée toutes les secondes. Dans les deux zsh
et ksh93
, cette variable peut également être rendue à virgule flottante (avec typeset -F SECONDS
) pour obtenir plus de précision. Ce n'est que l'heure de l'horloge murale, pas le temps CPU.
Je suis un peu en retard dans le train en marche, mais je voulais publier ma solution (pour une précision inférieure à la seconde) au cas où d'autres tomberaient sur ce fil lors de la recherche. La sortie est au format jours, heures, minutes et enfin secondes:
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)
LC_NUMERIC=C printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds
J'espère que quelqu'un trouvera cela utile!
Ma méthode pour bash
:
# Reset BASH time counter
SECONDS=0
#
# do stuff
#
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
Cette question est assez ancienne, mais en essayant de trouver ma façon préférée de le faire, ce fil est venu haut ... et je suis surpris que personne ne l'ait mentionné:
perf stat -r 10 -B sleep 1
'perf' est un outil d'analyse des performances inclus dans le noyau sous 'tools/perf' et souvent disponible pour être installé dans un paquet séparé ('perf' dans CentOS et 'linux-tools' sur Debian/Ubuntu). Le wiki Linux Kernal perf a beaucoup plus d'informations à ce sujet.
L'exécution de "perf stat" donne beaucoup de détails, y compris le temps d'exécution moyen juste à la fin:
1.002248382 seconds time elapsed ( +- 0.01% )
#!/bin/bash
start=$(date +%s.%N)
# HERE BE CODE
end=$(date +%s.%N)
runtime=$(python -c "print(${end} - ${start})")
echo "Runtime was $runtime"
Oui, cela appelle Python, mais si vous pouvez vivre avec cela, alors c'est une solution plutôt agréable et laconique.
Une petite fonction Shell qui peut être ajoutée avant les commandes pour mesurer leur temps:
tm() {
local start=$(date +%s)
$@
local exit_code=$?
echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}"
return $exit_code
}
Ensuite, utilisez-le dans votre script ou sur votre ligne de commande comme ceci:
tm the_original_command with all its parameters
Personnellement, j'aime envelopper tout mon code de script dans une fonction "principale" comme ceci:
main () {
echo running ...
}
# stuff ...
# calling the function at the very end of the script
time main
Remarquez à quel point il est facile d'utiliser la commande time
dans ce scénario. Évidemment, vous ne mesurez pas le temps précis, y compris le temps d'analyse du script, mais je le trouve suffisamment précis dans la plupart des situations.
En utilisant niquement bash, il est également possible de mesurer et calculer la durée d'une partie du script Shell (ou le temps écoulé pour l'ensemble du script):
start=$SECONDS
... # do time consuming stuff
end=$SECONDS
vous pouvez maintenant soit imprimer la différence:
echo "duration: $((end-start)) seconds."
si vous avez seulement besoin d'une durée incrémentielle, faites:
echo "duration: $((SECONDS-start)) seconds elapsed.."
Vous pouvez également stocker la durée dans une variable:
let diff=end-start
Voici une variante de la réponse d'Alex. Je ne me soucie que des minutes et des secondes, mais je voulais aussi qu'il soit formaté différemment. J'ai donc fait ceci:
start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
#!/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..."
La fonction de synchronisation basée sur SECONDS
, limitée à la granularité de second niveau uniquement, n'utilise aucune commande externe:
time_it() {
local start=$SECONDS ts ec
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Starting $*"
"$@"; ec=$?
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
# make sure to return the exit code of the command so that the caller can use it
return "$ec"
}
Par exemple:
time_it sleep 5
donne
2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds
#!/bin/bash
begin=$(date +"%s")
Script
termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
Pour bash, utilisez la variable interne $SECONDS
. Voici une démo:
Notez que dt_min
Est arrondi de 0.01666666666...
(1 seconde = autant de minutes) à 0.017
Dans ce cas puisque j'utilise la fonction printf
pour arrondir . La partie sleep 1;
Ci-dessous est l'endroit où vous appelleriez votre script pour exécuter et chronométrer, mais je dors juste pendant 1 seconde à la place de cette démo:
start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); echo "dt_sec = $dt_sec; dt_min = $dt_min"
dt_sec = 1; dt_min = 0.017
bc
et printf
dans ma réponse ici: https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division -in-bash/58479867 # 58479867