merlin.metso
merlin.metso

Reputation: 107

Bash script to watch execution time of other scripts

I have a main script which run all the scripts in a folder.

#!/bin/bash
for each in /some_folder/*.sh
do
  bash $each
done;

I want to know if execution of one of them lasts too long (more than N seconds). For example execution of script such as:

#!/bin/bash
ping -c 10000 google.com

will lasts very long, and I want my main script to e-mail me after N second.

All I can do now is to run all scripts with #timeout N option but it stops them! Is it possible to E-mail me and not to stop execution of script?

Upvotes: 7

Views: 427

Answers (2)

Gilles Quénot
Gilles Quénot

Reputation: 185025

Try this :

#!/bin/bash

# max seconds before mail alert
MAX_SECONDS=3600

# running the command in the background and get the pid
command_that_takes_a_long_time & _pid=$!

sleep $MAX_SECONDS

# if the pid is alive...
if kill &>/dev/null -0 $_pid; then
    mail -s "script $0 takes more than $MAX_SECONDS" [email protected] < /dev/null
fi

We run the command in the background, then sleep for MAX_SECONDS in // and alert by email if the process takes more than what is permitted.

Finally, with your specific requirements :

#!/bin/bash

MAX_SECONDS=3600

alerter(){
    bash "$1" & _pid=$!
    sleep $MAX_SECONDS
    if kill &>/dev/null -0 $_pid; then
        mail -s "$2 takes more than $MAX_SECONDS" [email protected] < /dev/null
    fi
}

for each in /some_folder/*.sh; do
    alerter "$each" &
    wait $_pid # remove this line if you wou'd like to run all scripts in //
done

Upvotes: 7

Thomas
Thomas

Reputation: 181745

You can do something like this:

( sleep 10 ; echo 'Takes a while' | sendmail [email protected] ) &
email_pid=$!
bash $each
kill $email_pid

The first command is run in a subshell in the background. It first sleeps a while, then sends email. If the script $each finishes before the sleep expires, the subshell is killed without sending email.

Upvotes: 4

Related Questions