J'écris un script en bash pour calculer le temps écoulé pour l'exécution de mes commandes, considérez:
STARTTIME=$(date +%s)
#command block that takes time to complete...
#........
ENDTIME=$(date +%s)
echo "It takes $($ENDTIME - $STARTTIME) seconds to complete this task..."
J'imagine que ma logique est correcte, mais je termine avec l'impression suivante:
"Cela prend quelques secondes pour terminer cette tâche ..."
Quelque chose ne va pas avec mon évaluation de chaîne?
Je crois que les variables bash ne sont pas typées, j'adorerais s'il existe néanmoins une méthode "chaîne en entier" dans bash.
$(())
ou $[]
travaillera au calcul du résultat d'une opération arithmétique. Vous utilisez $()
qui prend simplement la chaîne et l'évalue comme une commande. C'est un peu une distinction subtile. J'espère que cela t'aides.
Comme le remarque tink dans les commentaires sur cette réponse, $[]
est obsolète et $(())
doit être privilégié.
Je trouve très propre d'utiliser la variable interne "$ SECONDS"
SECONDS=0 ; sleep 10 ; echo $SECONDS
Vous essayez d'exécuter le nombre dans la ENDTIME
en tant que commande. Vous devriez également voir une erreur comme 1370306857: command not found
. Utilisez plutôt le expansion arithmétique :
echo "It takes $(($ENDTIME - $STARTTIME)) seconds to complete this task..."
Vous pouvez également enregistrer les commandes dans un script distinct, commands.sh
, et utiliser la commande time:
time commands.sh
Vous pouvez utiliser le mot clé time
de Bash ici avec une chaîne de format appropriée.
TIMEFORMAT='It takes %R seconds to complete this task...'
time {
#command block that takes time to complete...
#........
}
Voici ce que référence dit à propos de TIMEFORMAT
:
La valeur de ce paramètre est utilisée en tant que chaîne de format spécifiant la manière dont les informations de synchronisation des pipelines précédées du mot
time
reserved doivent être affichées. Le caractère "%
" introduit une séquence d'échappement qui est étendue à une valeur temporelle ou à une autre information. Les séquences d'échappement et leur signification sont les suivantes: les accolades indiquent les portions optionnelles.%% A literal ‘%’. %[p][l]R The elapsed time in seconds. %[p][l]U The number of CPU seconds spent in user mode. %[p][l]S The number of CPU seconds spent in system mode. %P The CPU percentage, computed as (%U + %S) / %R.
L'option facultative p est un chiffre spécifiant la précision, le nombre de chiffres fractionnaires après un point décimal. Une valeur de 0 ne génère aucun point décimal ni fraction. Trois points au plus après la virgule peuvent être spécifiés. les valeurs de p supérieures à 3 sont remplacées par 3. Si p est non spécifié, la valeur 3 est utilisée.
Le paramètre optionnel
l
spécifie un format plus long, y compris les minutes, de la forme MMmSS.FFs. La valeur de p détermine si la fraction est incluse ou non.Si cette variable n'est pas définie, Bash agit comme si elle avait la valeur
$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
Si la valeur est null, aucune information de minutage n'est affichée. Un retour à la ligne est ajouté lorsque la chaîne de format est affichée.
Essayez le code suivant:
start=$(date +'%s') && sleep 5 && echo "It took $(($(date +'%s') - $start)) seconds"
essayez d'utiliser le temps avec l'option secondes écoulées:
/usr/bin/time -f%e sleep 1
sous bash.
ou \time -f%e sleep 1
en bash interactif.
voir la page de manuel time:
Les utilisateurs du shell bash doivent utiliser un chemin explicite pour exécuter la commande time externe et non la variante intégrée du shell. Sur le système où l'heure est installée dans/usr/bin, le premier exemple deviendrait/usr/bin/time wc/etc/hosts
et
FORMATTING THE OUTPUT
...
% A literal '%'.
e Elapsed real (wall clock) time used by the process, in
seconds.
Pour de plus grands nombres, nous voudrons peut-être imprimer dans un format plus lisible. L'exemple ci-dessous fait la même chose qu'un autre, mais imprime également au format "humain":
secs_to_human() {
if [[ -z ${1} || ${1} -lt 60 ]] ;then
min=0 ; secs="${1}"
else
time_mins=$(echo "scale=2; ${1}/60" | bc)
min=$(echo ${time_mins} | cut -d'.' -f1)
secs="0.$(echo ${time_mins} | cut -d'.' -f2)"
secs=$(echo ${secs}*60|bc|awk '{print int($1+0.5)}')
fi
echo "Time Elapsed : ${min} minutes and ${secs} seconds."
}
Test simple:
secs_to_human "300"
secs_to_human "305"
secs_to_human "59"
secs_to_human "60"
secs_to_human "660"
secs_to_human "3000"
Sortie:
Time Elapsed : 5 minutes and 0 seconds.
Time Elapsed : 5 minutes and 5 seconds.
Time Elapsed : 0 minutes and 59 seconds.
Time Elapsed : 1 minutes and 0 seconds.
Time Elapsed : 11 minutes and 0 seconds.
Time Elapsed : 50 minutes and 0 seconds.
Pour utiliser un script comme décrit dans d’autres publications (point de départ de la capture, appelez la fonction avec l’heure de fin:
start=$(date +%s)
# << performs some task here >>
secs_to_mins_and_secs "$(($(date +%s) - ${start}))"