If the first day of the month is a Sunday it will indeed run.
The reason is that the two conditions "day of month" (third field) and "day of week" (fifth field) are not connected with an AND (both must occur) but with an OR (either one must occur). From man 5 crontab
:
Note: The day of a command's execution can be specified by two fields -- day of month, and day of week. If both fields are restricted (ie, are not *), the command will be run when either field matches the current time. For example, ``30 4 1,15 * 5'' would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.
So your cronjob will run at midnight every 1st and 2nd of the month and additionally every Mon, Tue, Wed, Thu, Fri and Sat of the month.
If you need to run the command only once in a month but not on Sunday, as you write in your comment, you must check the date in the command itself.
These are the conditions to run the command:
IF (date is 1st day of month AND date is not Sunday) OR (date is 2nd day of month AND yesterday was Sunday) THEN run command
You could write two cronjobs:
0 0 1 * * test $(date +\%u) -eq 7 || echo "today's the 1st day of the month but not Sun" 0 0 2 * * test $(date +\%u) -eq 1 && echo "today's Mon (=yesterday was Sun) and the 2nd day of the month"
The first cronjob will run every 1st day of the month at midnight:
date +%u
returns an integer where 1 is Mon, 2 is Tue, etc. (the ‘%’ needs to be escaped in a crontab).test
checks whether$(date +%u1)
equals7
(Sunday).||
is the OR boolean operator, it reacts to the return value of the previous command. Iftest
returns FALSE then the rest of the command is run.
The second cronjob will run every 2nd day of the month at midnight:
Again,
date +%u
returns an integer where 1 is Mon, 2 is Tue, etc.test
checks whether$(date +%u1)
equals1
(Monday).&&
is the AND boolean operator, iftest
returns TRUE then the rest of the command is run.