매월 마지막 날 일정 히고 있으며 몇 가지 다른 해결책을

나는 달의 마지막 날에 스크립트를 예약하라는 지시를 읽었습니다.

참고 :
영리한 독자는 매월 마지막 날에 실행할 명령을 설정하는 방법을 궁금해 할 수 있습니다. 매월 적용 할 dayofmonth 값을 설정할 수 없기 때문입니다. 이 문제는 리눅스와 유닉스 프로그래머들을 괴롭 히고 있으며 몇 가지 다른 해결책을 만들어 냈습니다. 일반적인 방법은 date 명령을 사용하여 내일 날짜가 01인지 확인하는 if-then 문을 추가하는 것입니다.

00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1

이렇게하면 매일 정오 12시에 해당 월의 마지막 날인지 확인하고, 그렇다면 cron이 명령을 실행합니다.

여기에 이미지 설명을 입력하십시오

어떻게 [`date +%d -d tomorrow` = 01 ]작동합니까?
상태가 정확 then; command1합니까?



답변

요약

올바른 코드는 다음과 같아야합니다.

#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"

이 스크립트를 호출하면 end_of_month.shcron의 호출은 다음과 같습니다.

00 12 28-31 * * /path/to/script/end_of_month.sh command

그러면 스크립트 end_of_month는 28, 29, 30 및 31 일에 한해 (내일은 해당 월의 마지막 날임을 확인합니다) 실행합니다. 다른 날에는 월말을 확인할 필요가 없습니다.

오래된 게시물.

이것은 Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons © 2015의 “Linux Command Line and Shell Scripting Bible”책에서 인용 한 것입니다.

예, 그것이 말하는 것이지만 그것은 잘못되었거나 불완전합니다.

  • 결산이 누락되었습니다 fi.
  • [다음 사이에 공간이 필요합니다 `.
  • 되어 강력 $ (…) 대신를 사용하는 것이 좋습니다 `…`.
  • 확장 과 같이 따옴표를 사용하는 것이 중요합니다."$(…)"
  • ;이후 에 추가 가 있습니다then

내가 어떻게 알아? (자, 경험 ☺)하지만 Shellcheck 시도 할 수 있습니다 . 책에서 별표 뒤에 코드를 붙여 넣으면 위에 나열된 오류와 “누락 된 세방”이 표시됩니다. Shellcheck에서 오류가없는 스크립트는 다음과 같습니다.


#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi

작성된 사이트는 “쉘 코드”이기 때문에 해당 사이트가 작동합니다. 그것은 많은 쉘에서 작동하는 구문입니다.

shellcheck에서 언급하지 않은 몇 가지 문제는 다음과 같습니다.

  • date 명령이 GNU 날짜 버전이라고 가정합니다. 값으로 -d허용 되는 옵션이 있는 옵션 tomorrow(busybox에는 -d 옵션이 있지만 내일은 이해하지 못하고 BSD에는 -d옵션이 있지만 “디스플레이”는 시간과 관련이 없습니다).

  • 형식을 설정하는 것이 좋습니다 모든 옵션 date -d tomorrow +'%d'.

  • cron 시작 시간은 항상 현지 시간으로, DST (일광 절약 시간)가 설정되거나 설정 해제 된 경우 작업이 정확한 요일보다 1 시간 늦게 시작될 수 있습니다.

우리가 한 것은 cron으로 호출 할 수있는 쉘 스크립트입니다. 다음과 같이 프로그램 또는 명령의 인수를 수락하도록 스크립트를 추가로 수정할 수 있습니다 (최종 올바른 코드).

#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"

이 스크립트를 호출하면 end_of_month.shcron의 호출은 다음과 같습니다.

00 12 28-31 * * /path/to/script/end_of_month.sh command

그러면 스크립트 end_of_month는 28, 29, 30 및 31 일에 한해 (내일은 해당 월의 마지막 날임을 확인합니다) 실행합니다. 다른 날에는 월말을 확인할 필요가 없습니다.

올바른 경로가 포함되어 있는지 확인하십시오. cron 내부의 PATH는 사용자 PATH와 같지 않을 것입니다.

참고 있다는 것을 하나의 달 스크립트의 최종 테스트는 (아래 표시) 다른 많은 유틸리티 나 스크립트를 호출 할 수 있었다.

또한 cron이 전체 명령 행에서 생성하는 추가 문제점을 피할 수 있습니다.

  • Cron은 또는로 %인용하더라도 명령 행을 분할합니다 ( 여기서는 작품 만 해당 ). 그것은 cron 작업이 실패하는 일반적인 방법입니다.'"\

end_of_month.sh가짜 시간으로 스크립트 를 테스트하여 스크립트가 특정 날짜에 작동하는지 (월말까지 기다리지 않고) 작동하는지 테스트 할 수 있습니다 .

$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....

답변

구문 오류가 수정되고 명령이 덜 장황하게 약간 수정되었다고 가정합니다.

00 12 28-31 * * [ "$( date -d tomorrow +\%d )" != "01" ] || command1

내일 날짜를 두 자리 숫자로 가져 오기 위해 (사용되는 date +%d -d tomorrowGNU라고 가정) 실행됩니다 date. 숫자가 아닌 경우 01, 다음 오늘 달의 마지막 날이 아니다. 이 경우, 시험은 성공하고 command1있다 하지 실행. 작업은 매월 마지막 날이 될 수있는 정오에 실행됩니다.

원래 명령 :

00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1

몇 가지 문제가 있습니다.

  • 뒤에 공백이 없습니다 [.
  • ;직접 후 then.
  • %cron 작업 스펙에서 특별하며로 \%참조 해야합니다 (참조 man 5 crontab).
  • fi끝에 일치하는 결승은 없습니다 if.

답변

매월 마지막 날을 예약하려면 다음을 시도하십시오 0 0 15,L * *..