유닉스 스크립트를 15 초마다 실행하는 방법은 무엇입니까?
나는 watch를 포함하여 몇 가지 해결책을 보았고 단순히 백그라운드에서 반복되는 (및 잠자는) 스크립트를 실행했지만 이상적인 것은 없습니다.
15 초마다 실행해야하는 스크립트가 있고 cron이 초를 지원하지 않기 때문에 다른 작업을해야합니다.
Unix에서 15 초마다 스크립트를 실행하는 가장 강력하고 효율적인 방법은 무엇입니까? 스크립트는 재부팅 후에도 실행되어야합니다.
cron을 사용하여 매분 스크립트를 실행하고 해당 스크립트가 실행 사이에 15 초의 휴면 상태로 스크립트를 4 번 실행하도록합니다.
(스크립트 실행이 빠르다고 가정합니다. 그렇지 않은 경우 절전 시간을 조정할 수 있습니다.)
이렇게하면 cron15 초의 실행 기간뿐만 아니라 모든 이점을 얻을 수 있습니다.
편집 : 아래 @bmb의 주석도 참조하십시오.
cron에서 스크립트를 실행해야하는 경우 :
* * * * * /foo/bar/your_script
* * * * * sleep 15; /foo/bar/your_script
* * * * * sleep 30; /foo/bar/your_script
* * * * * sleep 45; /foo/bar/your_script
스크립트 이름 및 경로를 / foo / bar / your_script로 바꿉니다.
위의 수정 된 버전 :
mkdir /etc/cron.15sec
mkdir /etc/cron.minute
mkdir /etc/cron.5minute
/ 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
백그라운드에서 실행하지 않습니까?
#!/bin/sh
while [ 1 ]; do
echo "Hell yeah!" &
sleep 15
done
이것은 얻는 것만 큼 효율적입니다. 중요한 부분은 15 초마다 실행되고 스크립트는 나머지 시간 동안 휴면합니다 (따라서 사이클을 낭비하지 않음).
cron보다 빠르게 스케줄러를 작성했습니다. 나는 또한 중첩 가드를 구현했습니다. 이전 프로세스가 아직 실행중인 경우 새 프로세스를 시작하지 않도록 스케줄러를 구성 할 수 있습니다. https://github.com/sioux1977/scheduler/wiki 에서 살펴보세요
nanosleep (2) 사용하십시오 . timespec나노초 정밀도로 시간 간격을 지정하는 데 사용되는 구조 를 사용합니다.
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#! /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
# the 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 or has no files
if [ ! "$(ls -A $dir/)" ]
then
exit
fi
# Sleep if both $delay and $counter are set
if [ ! -z $delay ] && [ ! -z $counter ]
then
sleep $delay
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 [ "0$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
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
To avoid possible overlapping of execution, use a locking mechanism as described in that thread.
참고URL : https://stackoverflow.com/questions/1034243/how-to-get-a-unix-script-to-run-every-15-seconds
'Programing' 카테고리의 다른 글
| UIScrollView에서 세로 스크롤 비활성화 (0) | 2020.09.20 |
|---|---|
| Python이 C ++보다 빠르고 가볍습니까? (0) | 2020.09.20 |
| Java : 이중 값에 대한 정밀도를 설정하는 방법은 무엇입니까? (0) | 2020.09.20 |
| EC2는 크기를 늘린 후 볼륨 크기를 조정할 수 없습니다. (0) | 2020.09.20 |
| "실행 대상 iOS 장치가 구성표를 실행하는 데 유효하지 않습니다." (0) | 2020.09.20 |