[unix] 유닉스 스크립트를 15 초마다 실행하는 방법은 무엇입니까?

나는 시계를 포함하여 몇 가지 해결책을 보았고 단순히 백그라운드에서 반복되는 (잠자기) 스크립트를 실행했지만 이상적인 것은 없었다.

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