11

I have a simple bash script that runs a series of checks (ping, nslookup, etc) and then sends an email report with the output of that data.

I'd like the email to include information on how long it took the entire script to run. Is there an easy way to collect that information?

15

I suggest to take a look at bash variable SECONDS:

SECONDS: Each time this parameter is referenced, the number of seconds since shell invocation is returned. If a value is assigned to SECONDS, the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned.

Thus you can simply print this variable at the end of the script. Alternatively, if your intention is to measure the time of only part of the program, then just set SECONDS=0 at the beginning of the measured block of commands, and at the end just use value stored in this variable.

  • I never knew about $SECONDS; that's great! To add to this, you can convert seconds into hours:minutes:seconds with something like date -d "1970-01-01 ${SECONDS} sec" +'%k:%M:%S' (see man date for more formatting options). – Sparhawk Feb 8 '15 at 0:19
  • I really like this approach but I'm still a little confused. Let's say I run the same script a couple of seconds apart from one another. If I set SECONDS=0 on one script and the same thing on another script, will they interfere with one another? – Mike B Feb 8 '15 at 3:20
  • 3
    Nevermind - I stumbled upon Tom's feedback in a Stack Overflow post (stackoverflow.com/a/5153036/344780) which essentially subtracts the difference START_TIME=$SECONDS; dosomething; ELAPSED_TIME=$(($SECONDS - $START_TIME)). This seems a bit more flexible for simultaneous use. – Mike B Feb 8 '15 at 5:52
8

Prefix your command with /usr/bin/time and the time command will output the time it took the script to run. This is more portable than the using something bash specific.

6

While using SECONDS and time will give you relative values. If you'd like to have absolute values for Auditing and Reporting Purposes as to when the script ran and when it completed, you might want to try something like this before and after your commands date '+%Y%m%d%H%M%S.%N' . This could also give you a better granularity as it can capture sub-second differences as you have commands like ping which normally execute within a second.

1

Nest your script. To send an email there are a number of options. I personally favour msmtp for this, you can define the headers yourself "here" style (inline) or use a separate file and cat them together. There are all sorts of alternatives to this involving perl, python etc.

Reply-To: someone@somehost
Sender: someone <someone@somehost>
To: somebody@somewhere.else
Subject: some subject
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset="iso-8859-1"

The trailing blank line is important. cat your assembled message into msmtp thusly :

cat assembled.eml | msmtp somebody@somewhere.else

A pessimist would loop until success a reasonable number of times.

The payload could also be html, and could be php generated.

A very ugly alternative for "batchy" operation overnight say is to create a cronjob and the output is emailed in lieu of stdout/stderr.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.