How to run a Linux script every few seconds under cron

From Computer Tyme Support Wiki

(Difference between revisions)
Jump to: navigation, search
Line 5: Line 5:
  # Run all programs in a directory in parallel
  # Run all programs in a directory in parallel
  # Usage: run-parallel directory delay
  # Usage: run-parallel directory delay
-
  # Copyright 2013 by Marc Perkel - http://www.junkemailfilter.com
+
  # Copyright 2013 by Marc Perkel
 +
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
  # Free to use with attribution
  # Free to use with attribution
   
   
Line 11: Line 12:
  then
  then
     echo
     echo
-
     echo "run-parallel by Marc Perkel - support@junkemailfilter.com"
+
     echo "run-parallel by Marc Perkel"
-
     echo "free to copy and use with attribution"
+
    echo
 +
     echo "This program is used to run all programs in a directory in parallel"
 +
    echo "or to rerun them every X seconds for one minute."
 +
    echo "Think of this program as cron with seconds resolution."
     echo
     echo
     echo "Usage: run-parallel [directory] [delay]"
     echo "Usage: run-parallel [directory] [delay]"
     echo
     echo
-
     echo "Example:"
+
     echo "Examples:"
     echo "  run-parallel /etc/cron.20sec 20"
     echo "  run-parallel /etc/cron.20sec 20"
-
     echo "  Runs all executable files in /etc/cron.20sec every 20 seconds."
+
     echo "  run-parallel 20"
 +
    echo "  # Runs all executable files in /etc/cron.20sec every 20 seconds or 3 times a minute."
     echo  
     echo  
     echo "If delay parameter is missing it runs everything once and exits."
     echo "If delay parameter is missing it runs everything once and exits."
 +
    echo "If only delay is passed then the directory /etc/cron.[delay]sec is assumed."
     echo
     echo
-
     echo "You could make a script containing the following and run it once a minute from cron for 2,3,4,5,6,10,12,15,20,30 second resolution."
+
     echo 'if "cronsec" is passed then it runs all of these delays 2 3 4 5 6 10 12 15 20 30'
-
     echo
+
     echo "resulting in 30 20 15 12 10 6 5 4 3 2 executions per minute."  
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.2sec 2 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.3sec 3 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.4sec 4 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.5sec 5 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.6sec 6 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.10sec 10 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.12sec 12 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.15sec 15 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.20sec 20 &"
+
-
    echo  "/usr/local/sbin/run-parallel /etc/cron.30sec 30 &"
+
     echo
     echo
     exit
     exit
  fi
  fi
 +
 +
# If "cronsec" is passed as a parameter then run all the delays in parallel
 +
 +
if [ $1 = cronsec ]
 +
then
 +
    $0 2 &
 +
    $0 3 &
 +
    $0 4 &
 +
    $0 5 &
 +
    $0 6 &
 +
    $0 10 &
 +
    $0 12 &
 +
    $0 15 &
 +
    $0 20 &
 +
    $0 30 &
 +
    exit
 +
fi
 +
 +
# Set the directory to first prameter and delay to second parameter
   
   
  dir=$1
  dir=$1
  delay=$2
  delay=$2
 +
 +
# If only parameter is 2,3,4,5,6,10,12,15,20,30 then automatically calculate standard directory name /etc/cron.[delay]sec
 +
 +
if [[ "$1" =~ ^(2|3|4|5|6|10|12|15|20|30)$ ]]
 +
then
 +
    dir="/etc/cron.$1sec"
 +
    delay=$1
 +
fi
   
   
  # Exit if directory doesn't exist
  # Exit if directory doesn't exist
Line 73: Line 96:
   
   
  # Run all the programs in the directory in parallel
  # Run all the programs in the directory in parallel
 +
# Use of timeout ensures that the processes are killed if they run too long
   
   
  for program in $dir/* ; do
  for program in $dir/* ; do
-
if [ -x $program ]  
+
    if [ -x $program ]  
     then
     then
-
       $program &> /dev/null &
+
       if [ $delay -gt 1 ]
 +
      then
 +
          timeout $delay $program &> /dev/null &
 +
      else
 +
          $program &> /dev/null &
 +
      fi
     fi
     fi
  done
  done

Revision as of 04:00, 9 January 2014

Did you ever want to run a program every few seconds under a linux, unix, bsd or osx cron script? Here's an ellegant script that does just that. You can get 2,3,4,5,6,10,12,15,20,30 second resolution.

#! /bin/sh

# Run all programs in a directory in parallel
# Usage: run-parallel directory delay
# Copyright 2013 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

if [ $# -eq 0 ]
then
   echo
   echo "run-parallel by Marc Perkel"
   echo
   echo "This program is used to run all programs in a directory in parallel" 
   echo "or to rerun them every X seconds for one minute."
   echo "Think of this program as cron with seconds resolution."
   echo
   echo "Usage: run-parallel [directory] [delay]"
   echo
   echo "Examples:"
   echo "   run-parallel /etc/cron.20sec 20"
   echo "   run-parallel 20"
   echo "   # Runs all executable files in /etc/cron.20sec every 20 seconds or 3 times a minute."
   echo 
   echo "If delay parameter is missing it runs everything once and exits."
   echo "If only delay is passed then the directory /etc/cron.[delay]sec is assumed."
   echo
   echo 'if "cronsec" is passed then it runs all of these delays 2 3 4 5 6 10 12 15 20 30'
   echo "resulting in 30 20 15 12 10 6 5 4 3 2 executions per minute." 
   echo
   exit
fi

# If "cronsec" is passed as a parameter then run all the delays in parallel

if [ $1 = cronsec ]
then
   $0 2 &
   $0 3 &
   $0 4 &
   $0 5 &
   $0 6 &
   $0 10 &
   $0 12 &
   $0 15 &
   $0 20 &
   $0 30 &
   exit
fi

# Set the directory to first prameter and delay to second parameter

dir=$1
delay=$2

# If only parameter is 2,3,4,5,6,10,12,15,20,30 then automatically calculate standard directory name /etc/cron.[delay]sec

if 3|4|5|6|10|12|15|20|30)$ 
then
   dir="/etc/cron.$1sec"
   delay=$1
fi

# Exit if directory doesn't exist

if ! [ -d $dir ]
then
   exit
fi

# Exit if directory has no files

if ! [ "$(ls -A $dir/)" ]
then
   exit
fi

# Sleep if both $delay and $counter are set

if ! [ -z $delay ]
then
   if ! [ -z $counter ]
   then
      sleep $delay
   fi
fi

# Set counter to 0 if not set

if [ -z $counter ]
then
   counter=0
fi

# Run all the programs in the directory in parallel
# Use of timeout ensures that the processes are killed if they run too long

for program in $dir/* ; do
   if [ -x $program ] 
   then
      if [ $delay -gt 1 ] 
      then
         timeout $delay $program &> /dev/null &
      else
         $program &> /dev/null &
      fi
   fi
done

# If delay not set then we're done

if [ -z $delay ]
then
   exit
fi

# Add delay to counter

counter=$(( $counter + $delay ))

# If minute is not up - call self recursively

if [ $counter -lt 60 ]
then
   . $0 $dir $delay &
fi

# Otherwise we're done

Then you create a script that you run every minute. Here's an example called 00-minute

/usr/local/sbin/run-parallel /etc/cron.2sec 2 &
/usr/local/sbin/run-parallel /etc/cron.3sec 3 &
/usr/local/sbin/run-parallel /etc/cron.4sec 4 &
/usr/local/sbin/run-parallel /etc/cron.5sec 5 &
/usr/local/sbin/run-parallel /etc/cron.6sec 6 &
/usr/local/sbin/run-parallel /etc/cron.10sec 10 &
/usr/local/sbin/run-parallel /etc/cron.12sec 12 &
/usr/local/sbin/run-parallel /etc/cron.15sec 15 &
/usr/local/sbin/run-parallel /etc/cron.20sec 20 &
/usr/local/sbin/run-parallel /etc/cron.30sec 30 &

You could eliminate the lines of times you aren't going to use but it doesn't matter because if there's no directory or nothing to run in the directory then it just skips that almost instantly. Be sure to create the directories for the time periods you want to use.

To run 00-minute every minute you can edit your /etc/crontab file and add:

* * * * * root /usr/local/sbin/00-minute
Personal tools