매일 1 시간 후에 크론 잡을 시작하려면 어떻게해야합니까?


16

매일 cronjob을 시작해야하지만 매일 1 시간 후에 시작해야합니다. 내가 지금까지 가지고있는 것은 일년 중 1 일을 제외하고 대부분 작동합니다.

0 0 * * * sleep $((3600 * (10#$(date +\%j) \% 24))) && /usr/local/bin/myprog

일이 365 일 때 작업은 5시에 시작하지만 다음 날 (윤년을 계산하지 않음)은 1로 표시되므로 작업은 1시에 시작합니다. 이 코너 케이스를 어떻게 제거 할 수 있습니까?


1
25 시간마다 시작하지 않는 이유는 무엇입니까?
HalosGhost

7
정확히 어떻게 하시겠습니까? 시간 위치의 * / 25는 해결되지 않습니다.
자작 나무

@HalosGhost 제안 해 주셔서 감사합니다! at를 기반으로 간단한 구현을 작성했습니다.
Giulio Muscarello

답변:


23

내가 선호하는 솔루션은 매 시간마다 작업을 시작하지만 스크립트 자체가 실행 시간인지 여부를 확인하고 25 중 24 번 아무것도하지 않고 종료하도록하는 것입니다.

크론 탭 :

0 * * * *    /usr/local/bin/myprog

상단에 myprog:

[ 0 -eq $(( $(date +%s) / 3600 % 25 )) ] || exit 0

스크립트 자체를 변경하지 않으려는 경우 crontab 항목에 "실행 시간"검사를 추가 할 수도 있지만보기 흉한 줄이 있습니다.

0 * * * *    [ 0 -eq $(( $(date +\%s) / 3600 \% 25 )) ] && /usr/local/bin/myprog

1
crontab에서 백 슬래시로 '%'을 (를) 이스케이프해야합니다.
자작 나무

@birch 나는 그것을 전혀 몰랐다! 나는 전에 crontab에 %를 포함시키지 않았다고 생각합니다. 수정 해 주셔서 감사합니다. 답변을 수정했습니다.
Celada

1
이것은 나에게 좋아 보인다. 일광 절약 시간 (봄이 다가오고 뒤 떨어짐)과 관련하여 OP가 무엇을하고 싶은지 모르겠지만 OP는 이에 따라 조정해야합니다.
emory

부서의 반올림에 대해 약간 걱정할 것입니다. 어떤 이유로 date커널에서 돌아온 1ms시간이 스크립트 실행을 예상 한 시간 이전 인 경우 검사 결과가 올바르지 않습니다.
kasperd

1
@kasperd 모르겠다. 다른 CPU가 다른 시간을보고하는 것이 옳을 것이라고 생각합니다. 에 관해서는 ntpd, 시계를 돌리고 점프하지 말고, 특히 이런 종류의 문제를 피하기 위해 열심히 노력하지만, ntpdate때로는 맞습니다 . cron수면 지연 을 잘못 계산하는 경우 버그로 간주됩니다. 그럼에도 불구하고, 3600 MOD 점은 촬영 및 해결 방법은 문제를 일으키는 ... 또는 reamainder을 촬영하기 전에 산술 식에 ± 1,800를 추가하는 작업을 가능성이 적습니다 시간 지난 30 분 예약하는 것
Celada

7

시스템이 시스템화 된 경우이를 위해 타이머 이벤트를 사용할 수 있습니다. 실행하려는 명령 / 태스크가 포함 된 새 서비스를 정의한 다음 OnUnitActiveSec옵션으로 타이머 이벤트를 작성하십시오 .

[Unit]
Description=daily + 1 hour task

[Timer]
OnUnitActiveSec=25h # run 25 hours after service was last started
AccuracySec=10min

[Install]
WantedBy=timers.target

을 사용하는 것을 제외하고 파일에 동일한 이름을 .service사용하십시오 .timer.

합성 :

  1. 디렉토리 job.service에서 호출 된 파일을 작성하십시오 /etc/systemd/system/.
  2. 필요한 정보로 채우십시오. 을 사용하여 구성을 확인할 수 있습니다 systemctl status job.service.
  3. 라는 파일 작성 job.timer에를 /etc/systemd/system/.
  4. 필요한 정보로 채우십시오.

    [Unit]
    Description=daily + 1 hour task
    
    [Timer]
    OnUnitActiveSec=25h # run 25 hours after service was last started
    AccuracySec=10min
    
    [Install]
    WantedBy=timers.target
    
  5. 타이머를 사용하여 확인 systemctl list-timers
  6. 끝난.

cron의 단순성에서 벗어나려면 launchd를 사용하면 systemd에 대한 예제보다 적은 작업이 필요합니다.
자작 나무

6

cronjobs 이외의 것을 사용하는 것이 마음에 들지 않으면 덜 알려진 유틸리티를 제안합니다 at. 25 시간 안에 실행되도록 예약 한 다음 프로그램을 호출하는 래퍼 스크립트를 작성하기 만하면됩니다. 이것은 가장 깨끗한 해결책 인 것 같습니다.
예를 들어 이것을 ~ / script.sh에 작성할 수 있습니다.

echo "bash ~/script.sh" | at now + 25 hours
/usr/bin/yourprogram

그리고 한 bash ~/script.sh번만 실행하십시오 .

25 시간 내에 한 번 작업을 예약한다는 아이디어에 대해 @HalosGhost에게 감사합니다.


2
at이 목적 으로 사용 하는 데는 두 가지 문제점 이 있습니다. (1) 작업이 한 번만 올바르게 실행되지 않으면 자체 일정을 변경하지 못하고 다음 실행뿐만 아니라 향후 모든 실행이 사람이 통지 할 때까지 효과적으로 취소됩니다. (2) 작업을 실행하는 데 0이 아닌 시간이 걸리기 때문에 순진함을 사용하면 now + 25 hours매번 몇 초 (또는 그 이상) 후에 실행됩니다.이 지연은 시간이 지남에 따라 쌓여 결국 완전히 잘못 실행됩니다. 시각.
Celada

2
# 1에 대해 맞습니다. # 2에 대해 잘 모르겠습니다. 데이터가 없지만 시계 변경과 작업 중 트리거 및 일정 변경 사이의 지연이 눈에 띄게 충분히 커질 것이라고 생각하지 않습니다. 특히 해상도 at가 몇 분으로 제한되어 모든 작업을 시작 한다고 생각하면 [시간] : 00.
Giulio Muscarello

1
@Celada : at 스크립트에서 다음 at작업을 먼저 예약 하면 이러한 문제를 피할 수 있습니다. 에도 불구하고, 경우 오류가 발생 후 전체 체인 또는 원하는되지 않을 수있는, 고장 : 유스 케이스 인 경우가 아니라 다시 시작이 큰 특징이다 "그것이 작동하는 경우에만이"를 실행하게됩니다. 그러나 유스 케이스가 "마지막으로 실패하더라도 항상 실행"인 경우 at올바른 도구가 아닙니다.
감독
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.