매일 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.