How to get a unix script to run every 15 seconds?

前端 未结 9 580
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 19:35

I\'ve seen a few solutions, including watch and simply running a looping (and sleeping) script in the background, but nothing has been ideal.

I have a script that ne

相关标签:
9条回答
  • 2020-11-28 19:57

    I would use cron to run a script every minute, and make that script run your script four times with a 15-second sleep between runs.

    (That assumes your script is quick to run - you could adjust the sleep times if not.)

    That way, you get all the benefits of cron as well as your 15 second run period.

    Edit: See also @bmb's comment below.

    0 讨论(0)
  • 2020-11-28 19:57

    Modified version of the above:

    mkdir /etc/cron.15sec
    mkdir /etc/cron.minute
    mkdir /etc/cron.5minute
    

    add to /etc/crontab:

    * * * * * root run-parts /etc/cron.15sec > /dev/null 2> /dev/null
    * * * * * root sleep 15; run-parts /etc/cron.15sec > /dev/null 2> /dev/null
    * * * * * root sleep 30; run-parts /etc/cron.15sec > /dev/null 2> /dev/null
    * * * * * root sleep 45; run-parts /etc/cron.15sec > /dev/null 2> /dev/null
    
    * * * * * root run-parts /etc/cron.minute > /dev/null 2> /dev/null
    */5 * * * * root run-parts /etc/cron.5minute > /dev/null 2> /dev/null
    
    0 讨论(0)
  • 2020-11-28 20:02

    Since my previous answer I came up with another solution that is different and perhaps better. This code allows processes to be run more than 60 times a minute with microsecond precision. You need the usleep program to make this work. Should be good to up to 50 times a second.

    #! /bin/sh
    
    # Microsecond Cron
    # Usage: cron-ms start
    # Copyright 2014 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
    
    basedir=/etc/cron-ms
    
    if [ $# -eq 0 ]
    then
       echo
       echo "cron-ms by Marc Perkel"
       echo
       echo "This program is used to run all programs in a directory in parallel every X times per minute."
       echo "Think of this program as cron with microseconds resolution."
       echo
       echo "Usage: cron-ms start"
       echo
       echo "The scheduling is done by creating directories with the number of"
       echo "executions per minute as part of the directory name."
       echo
       echo "Examples:"
       echo "  /etc/cron-ms/7      # Executes everything in that directory  7 times a minute"
       echo "  /etc/cron-ms/30     # Executes everything in that directory 30 times a minute"
       echo "  /etc/cron-ms/600    # Executes everything in that directory 10 times a second"
       echo "  /etc/cron-ms/2400   # Executes everything in that directory 40 times a second"
       echo
       exit
    fi
    
    # If "start" is passed as a parameter then run all the loops in parallel
    # The number of the directory is the number of executions per minute
    # Since cron isn't accurate we need to start at top of next minute
    
    if [ $1 = start ]
    then
       for dir in $basedir/* ; do
          $0 ${dir##*/} 60000000 &
       done
       exit
    fi
    
    # Loops per minute and the next interval are passed on the command line with each loop
    
    loops=$1
    next_interval=$2
    
    # Sleeps until a specific part of a minute with microsecond resolution. 60000000 is full minute
    
    usleep $(( $next_interval - 10#$(date +%S%N) / 1000 ))
    
    # Run all the programs in the directory in parallel
    
    for program in $basedir/$loops/* ; do
       if [ -x $program ] 
       then
          $program &> /dev/null &
       fi
    done
    
    # Calculate next_interval
    
    next_interval=$(($next_interval % 60000000 + (60000000 / $loops) ))
    
    # If minute is not up - call self recursively
    
    if [ $next_interval -lt $(( 60000000 / $loops * $loops)) ]
    then
       . $0 $loops $next_interval &
    fi
    
    # Otherwise we're done
    
    0 讨论(0)
  • 2020-11-28 20:09

    Won't running this in the background do it?

    #!/bin/sh
    while [ 1 ]; do
        echo "Hell yeah!" &
        sleep 15
    done
    

    This is about as efficient as it gets. The important part only gets executed every 15 seconds and the script sleeps the rest of the time (thus not wasting cycles).

    0 讨论(0)
  • 2020-11-28 20:11

    If you insist of running your script from cron:

    * * * * * /foo/bar/your_script
    * * * * * sleep 15; /foo/bar/your_script
    * * * * * sleep 30; /foo/bar/your_script
    * * * * * sleep 45; /foo/bar/your_script
    

    and replace your script name&path to /foo/bar/your_script

    0 讨论(0)
  • 2020-11-28 20:12

    I wrote a scheduler faster than cron. I have also implemented an overlapping guard. You can configure the scheduler to not start new process if previous one is still running. Take a look at https://github.com/sioux1977/scheduler/wiki

    0 讨论(0)
提交回复
热议问题