Script Bash pour calculer le temps écoulé

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..." 

Je suppose que ma logique est correcte mais je me retrouve avec l’impression suivante:

“Cela prend des 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’aimerais bien qu’il y ait néanmoins une méthode “ssortingng to integer” dans bash.

Soit $(()) soit $[] fonctionnera pour calculer le résultat d’une opération arithmétique. Vous utilisez $() qui prend simplement la chaîne et l’évalue en tant que commande. C’est un peu une distinction subtile. J’espère que cela t’aides.

Comme souligné dans les commentaires sur cette réponse, $[] est déconseillé et $(()) devrait ê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 numéro dans ENDTIME tant que commande. Vous devriez également voir une erreur comme 1370306857: command not found . Utilisez plutôt l’ 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 time clé time de Bash 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 dit la référence à propos de TIMEFORMAT :

La valeur de ce paramètre est utilisée comme une chaîne de format spécifiant comment les informations de synchronisation des pipelines préfixées par le mot réservé dans le time doivent être affichées. Le caractère ‘ % ‘ introduit une séquence d’échappement étendue à une valeur temporelle ou à d’autres informations. Les séquences d’échappement et leur signification sont les suivantes: les accolades indiquent des portions facultatives.

 %% 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. 

Le p optionnel 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. Au maximum trois endroits après le point décimal peuvent être spécifiés; les valeurs de p supérieures à 3 sont remplacées par 3. Si p n’est pas spécifié, la valeur 3 est utilisée.

L’option 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 nulle, aucune information de synchronisation n’est affichée. Une nouvelle ligne de fin est ajoutée 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 l’heure avec l’option secondes écastings:

/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. 
 start=$(date +%Y%m%d%H%M%S); for x in {1..5}; do echo $x; sleep 1; done; end=$(date +%Y%m%d%H%M%S); elapsed=$(($end-$start)); ftime=$(for((i=1;i<=$((${#end}-${#elapsed}));i++)); do echo -n "-"; done; echo ${elapsed}); echo -e "Start : ${start}\nStop : ${end}\nElapsed: ${ftime}" Start : 20171108005304 Stop : 20171108005310 Elapsed: -------------6 
  #!/bin/bash time_elapsed(){ appstop=$1; appstart=$2 ss_strt=${appstart:12:2} ;ss_stop=${appstop:12:2} mm_strt=${appstart:10:2} ;mm_stop=${appstop:10:2} hh_strt=${appstart:8:2} ; hh_stop=${appstop:8:2} dd_strt=${appstart:6:2} ; dd_stop=${appstop:6:2} mh_strt=${appstart:4:2} ; mh_stop=${appstop:4:2} yy_strt=${appstart:0:4} ; yy_stop=${appstop:0:4} if [ "${ss_stop}" -lt "${ss_strt}" ]; then ss_stop=$((ss_stop+60)); mm_stop=$((mm_stop-1)); fi if [ "${mm_stop}" -lt "0" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi if [ "${mm_stop}" -lt "${mm_strt}" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi if [ "${hh_stop}" -lt "0" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi if [ "${hh_stop}" -lt "${hh_strt}" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi if [ "${dd_stop}" -lt "0" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi if [ "${dd_stop}" -lt "${dd_strt}" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi if [ "${mh_stop}" -lt "0" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi if [ "${mh_stop}" -lt "${mh_strt}" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi ss_espd=$((10#${ss_stop}-10#${ss_strt})); if [ "${#ss_espd}" -le "1" ]; then ss_espd=$(for((i=1;i<=$((${#ss_stop}-${#ss_espd}));i++)); do echo -n "0"; done; echo ${ss_espd}); fi mm_espd=$((10#${mm_stop}-10#${mm_strt})); if [ "${#mm_espd}" -le "1" ]; then mm_espd=$(for((i=1;i<=$((${#mm_stop}-${#mm_espd}));i++)); do echo -n "0"; done; echo ${mm_espd}); fi hh_espd=$((10#${hh_stop}-10#${hh_strt})); if [ "${#hh_espd}" -le "1" ]; then hh_espd=$(for((i=1;i<=$((${#hh_stop}-${#hh_espd}));i++)); do echo -n "0"; done; echo ${hh_espd}); fi dd_espd=$((10#${dd_stop}-10#${dd_strt})); if [ "${#dd_espd}" -le "1" ]; then dd_espd=$(for((i=1;i<=$((${#dd_stop}-${#dd_espd}));i++)); do echo -n "0"; done; echo ${dd_espd}); fi mh_espd=$((10#${mh_stop}-10#${mh_strt})); if [ "${#mh_espd}" -le "1" ]; then mh_espd=$(for((i=1;i<=$((${#mh_stop}-${#mh_espd}));i++)); do echo -n "0"; done; echo ${mh_espd}); fi yy_espd=$((10#${yy_stop}-10#${yy_strt})); if [ "${#yy_espd}" -le "1" ]; then yy_espd=$(for((i=1;i<=$((${#yy_stop}-${#yy_espd}));i++)); do echo -n "0"; done; echo ${yy_espd}); fi echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}" #return $(echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}") } mh_days(){ mh_stop=$1; yy_stop=$2; #also checks if it's leap year or not case $mh_stop in [1,3,5,7,8,10,12]) mh_stop=31 ;; 2) (( !(yy_stop % 4) && (yy_stop % 100 || !(yy_stop % 400) ) )) && mh_stop=29 || mh_stop=28 ;; [4,6,9,11]) mh_stop=30 ;; esac return ${mh_stop} } appstart=$(date +%Y%m%d%H%M%S); read -p "Wait some time, then press nay-key..." key; appstop=$(date +%Y%m%d%H%M%S); elapsed=$(time_elapsed $appstop $appstart); echo -e "Start...: ${appstart:0:4}-${appstart:4:2}-${appstart:6:2} ${appstart:8:2}:${appstart:10:2}:${appstart:12:2}\nStop....: ${appstop:0:4}-${appstop:4:2}-${appstop:6:2} ${appstop:8:2}:${appstop:10:2}:${appstop:12:2}\n$(printf '%0.1s' "="{1..30})\nElapsed.: ${elapsed}" exit 0 -------------------------------------------- return Wait some time, then press nay-key... Start...: 2017-11-09 03:22:17 Stop....: 2017-11-09 03:22:18 ============================== Elapsed.: 0000-00-00 00:00:01