I am writing a script in bash to calculate the time elapsed for the execution of my commands, consider:
STARTTIME=$(date +%s)
#command block that takes time to c
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
For larger numbers we may want to print in a more readable format. The example below does same as other but also prints in "human" format:
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."
}
Simple testing:
secs_to_human "300"
secs_to_human "305"
secs_to_human "59"
secs_to_human "60"
secs_to_human "660"
secs_to_human "3000"
Output:
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.
To use in a script as described in other posts (capture start point then call the function with the finish time:
start=$(date +%s)
# << performs some task here >>
secs_to_human "$(($(date +%s) - ${start}))"
I find it very clean to use the internal variable "$SECONDS"
SECONDS=0 ; sleep 10 ; echo $SECONDS
Try the following code:
start=$(date +'%s') && sleep 5 && echo "It took $(($(date +'%s') - $start)) seconds"
This is a one-liner alternative to Mike Q's function:
secs_to_human() {
echo "$(( ${1} / 3600 ))h $(( (${1} / 60) % 60 ))m $(( ${1} % 60 ))s"
}
You can use Bash's time
keyword here with an appropriate format string
TIMEFORMAT='It takes %R seconds to complete this task...'
time {
#command block that takes time to complete...
#........
}
Here's what the reference says about TIMEFORMAT:
The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the
time
reserved word should be displayed. The ‘%
’ character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows; the braces denote optional portions.%% 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.
The optional p is a digit specifying the precision, the number of fractional digits after a decimal point. A value of 0 causes no decimal point or fraction to be output. At most three places after the decimal point may be specified; values of p greater than 3 are changed to 3. If p is not specified, the value 3 is used.
The optional
l
specifies a longer format, including minutes, of the form MMmSS.FFs. The value of p determines whether or not the fraction is included.If this variable is not set, Bash acts as if it had the value
$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'
If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed.