매월 말일에 스크립트를 예약하라는 지침을 읽었습니다.
노트:
기민한 독자들은 매달 마지막 날에 명령을 실행하도록 설정하는 방법에 대해 궁금할 것입니다. 왜냐하면 매달 해당하는 dayofmonth 값을 설정할 수 없기 때문입니다. 이 문제는 오랫동안 Linux 및 Unix 프로그래머를 괴롭혔으며 다양한 솔루션을 탄생시켰습니다. 일반적인 접근 방식은 if-then 문을 추가하고 date 명령을 사용하여 내일 날짜가 01인지 확인하는 것입니다.00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
매일 정오 12시에 해당 월의 마지막 날인지 확인하여, 그렇다면 cron이 명령을 실행합니다.
어떻게 [`date +%d -d tomorrow` = 01 ]
작동하나요?
진술이 정확합니까 then; command1
?
답변1
추상적인
올바른 코드는 다음과 같아야 합니다.
#!/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
이는 28, 29, 30, 31일에만 스크립트를 실행합니다 end_of_month
(내부적으로 해당 월의 마지막 날인지 확인합니다). 다른 날짜의 월말을 확인할 필요가 없습니다.
오래된 게시물.
이것은 Richard Blum과 Christine Bresnahan이 쓴 "Linux Command Line and Shell Scripting Bible"(442페이지, 3판, John Wiley & Sons ©2015)의 인용문입니다.
예, 그렇게 쓰여 있지만 잘못되었거나 불완전합니다.
- 결론적 발언이 누락되었습니다
fi
. [
와 뒤에는 공백이 필요합니다`
.- 이것은강하게대신 $(...) 를 사용하는 것이 좋습니다
`…`
. - 따옴표를 사용하는 것이 중요합니다.확장하다좋다
"$(…)"
;
나중에 보충이 있어요then
내가 어떻게 알아? (음, 경험상 ☺) 하지만 시도해 볼 수 있습니다주택 검사. 별표 뒤에 책의 코드를 붙여넣으면 "missing shebang"과 함께 위에 나열된 오류가 표시됩니다. 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'
.크론 시작 시간은 항상 현지 시간이므로 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
이는 28, 29, 30, 31일에만 스크립트를 실행합니다 end_of_month
(내부적으로 해당 월의 마지막 날인지 확인합니다). 다른 날짜의 월말을 확인할 필요가 없습니다.
올바른 경로를 포함했는지 확인하세요. cron 내의 PATH는 사용자의 PATH와 동일하지 않을 것입니다.
있습니다.하나월말 스크립트테스트를 거쳤습니다.(아래 표시)은 다른 많은 유틸리티나 스크립트를 호출할 수 있습니다.
또한 전체 명령줄을 사용하여 cron 생성과 관련된 추가 문제를 방지할 수 있습니다.
%
Cron은 명령줄을 사용하거나'
참조 하는 경우에도 모든 명령줄에서 명령줄을 분할합니다"
(여기에서는 a만\
유효합니다). 이는 크론 작업이 실패하는 일반적인 방법입니다.
faketime 테스트 스크립트를 사용하여 특정 날짜에 스크립트가 작동하는지 테스트 할 수 있습니다 end_of_month.sh
(작동하지 않는지 확인하기 위해 월말까지 기다릴 필요가 없습니다).
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....
답변2
구문 오류가 수정되고 명령이 덜 장황하게 약간 다시 작성되었다고 가정합니다.
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
.
답변3
매월 마지막 날을 예약하려면 다음을 시도해 보세요 0 0 15,L * *
.
답변4
당신의 크론탭에서
00 01 * * * [ $(date +\%d) -eq $(date \-d "-$(date +\%d) days month" +\%d) ] && /path/to/script.sh
위 내용은 매월 말일 오전 1시에 실행됩니다.