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

前端 未结 9 608
佛祖请我去吃肉
佛祖请我去吃肉 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 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
    

提交回复
热议问题