Czy 31 niekoniecznie oznacza koniec miesiąca w pracy crona?

13

W przypadku zadania cron wiemy, że możemy ustawić czas jak poniżej.

# +------------ Minute (0 - 59)
# | +---------- Hour (0 - 23)
# | | +-------- Day of the Month (1 - 31)
# | | | +------ Month (1 - 12)
# | | | | +---- Day of the Week (0 - 7) (Sunday is 0 or 7)
# | | | | |
# * * * * * command

Chcę wiedzieć, że kiedy ustalamy dzień 31 miesiąca, oznacza to koniec każdego miesiąca, chociaż miesiąc nie ma dnia 31. Mam nadzieję, że otrzymam odpowiedź.

Z góry dziękuję

squillman
źródło

Odpowiedzi:

22

Nie, 31 oznacza 31.

Możesz jednak zrobić oszustwo. Ustaw zadanie do uruchomienia w dowolnym dniu, który może potencjalnie być ostatnim dniem miesiąca (tj. 28–31 w polu dnia miesiąca), a następnie zastąp swoje polecenie wyrażeniem powłoki zawierającym test na datę chroniącą Komenda:

0 0 28-31 * * [ "`date +%m`" != "`date --date=tomorrow +%m`" ] && command

Wyrażenie w nawiasach testowych pyta tylko, czy dzisiejszy numer miesiąca jest inny niż numer miesiąca jutro, co oczywiście będzie prawdą tylko w ostatnim dniu miesiąca. Zauważ, że forma tego wyrażenia zależy od twojego lokalnego date- być może będziesz musiał go poprawić, jeśli nie masz aktualnej wersji GNU.

Powinienem powiedzieć, że tego nie wymyśliłem - znalazłem to dzięki szybkiemu Google w poście na liście mailowej autorstwa Matthew Jarvisa. Wyobrażam sobie jednak, że jest to standardowa sztuczka starego czarodzieja uniksowego.

Tom Anderson
źródło
1
Nie może to być zbyt stara sztuczka, biorąc pod uwagę specyficzne dla GNU opcje „date” =)
jj33,
4
Na stronach stackexchange zadawanie pytań, na które można znaleźć odpowiedź w wyszukiwarce Google, NIE jest złą rzeczą. W rzeczywistości jest to dobra rzecz, ponieważ następna osoba, która przeszuka to w Google, znajdzie odpowiedź na stackexchange i przyjdzie tutaj.
miernik
12

Nie, myślę, że najlepsze, co możesz zrobić, to uruchomić o północy pierwszego dnia miesiąca lub skonfigurować indywidualne linie crontab na każdy miesiąc (lub przynajmniej linię na miesiące z 28, 29, 30 i 31 dni)

0 0 28,29 2               * /my/command
0 0 30    4,6,9,11        * /my/command
0 0 31    1,3,5,7,8,10,12 * /my/command
Paul Dixon
źródło
Dzięki Paul! Pójdę za drugim. Czy w przypadku drugiej metody muszę ustawić ten sam plik trzy razy, prawda? Jeszcze raz dziękuję :)
Tak, musisz to powtórzyć.
Paul Dixon,
7
Nie mam doświadczenia z cronem, ale czy „0 0 28,29 2” nie wykonałby dwa razy w roku przestępnym? Nie żeby to był problem przez następne dwa lata, ale nadal ...
Wim ten Brink
To dobry punkt, nie jest to łatwe
Paul Dixon
4

Nie sądzę, że możesz to zrobić łatwo w crontab.

Jedną z opcji byłoby ustawienie, cronaby skrypt był uruchamiany codziennie, a następnie sam skrypt sprawdzał, czy jest to ostatni dzień miesiąca.

Dave Webb
źródło
3

Myślę, że cron ma specjalny znak „L” przeznaczony do tego celu:

*    *    L    *    *    your_script.sh 

wykona skrypt w ostatnim dniu każdego miesiąca

Z drugiej strony,

*    *    0    *    *    your_script.sh

Możesz nawet określić coś takiego:

*    *    *    *    1,5L    your_scrript.sh

aby uruchomić skrypt w ostatni poniedziałek i piątek każdego miesiąca

lub

*    *    *    *    1    your_script.sh

uruchamiać skrypt w każdy poniedziałek o północy.

Saasira
źródło
0

Spowoduje to wykonanie zadania:

if [ $( date +%-d --date="tomorrow" ) -eq 1 ]
then echo Last day of the current month
else echo Not yet!
     exit 0
fi

exit 1
Phil
źródło