나는 달의 마지막 날에 스크립트를 예약하라는 지시를 읽었습니다.
참고 :
영리한 독자는 매월 마지막 날에 실행할 명령을 설정하는 방법을 궁금해 할 수 있습니다. 매월 적용 할 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.sh
cron의 호출은 다음과 같습니다.
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.sh
cron의 호출은 다음과 같습니다.
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 tomorrow
GNU라고 가정) 실행됩니다 date
. 숫자가 아닌 경우 01
, 다음 오늘 달의 마지막 날이 아니다. 이 경우, 시험은 성공하고 command1
있다 하지 실행. 작업은 매월 마지막 날이 될 수있는 정오에 실행됩니다.
원래 명령 :
00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
몇 가지 문제가 있습니다.
- 뒤에 공백이 없습니다
[
. ;
직접 후then
.%
cron 작업 스펙에서 특별하며로\%
참조 해야합니다 (참조man 5 crontab
).fi
끝에 일치하는 결승은 없습니다if
.
답변
매월 마지막 날을 예약하려면 다음을 시도하십시오 0 0 15,L * *
..