Standard crontab — the multi-cron workaround
POSIX crontab has no last-day token, so you simulate it by enumerating the actual last day of each month. There are three groups: 30-day months, 31-day months, and February.
# 30-day months: April, June, September, November 0 0 30 4,6,9,11 * /path/to/script.sh # 31-day months 0 0 31 1,3,5,7,8,10,12 * /path/to/script.sh # February (leap-year safe — fires both 28th and 29th in leap years) 0 0 28,29 2 * /path/to/script.sh
The leap-year line is the trickiest. In non-leap years, only the 28th exists, so the cron fires once. In leap years, both the 28th and 29th exist; cron fires on both. To fire only on the actual last day, gate the script:
0 0 28,29 2 * [ "$(date -d tomorrow +%d)" = "01" ] && /path/to/script.sh
The wrapper checks “is tomorrow the 1st?”. Only on the actual last day of February (28th in non-leap, 29th in leap) is the answer yes.