LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 06-12-2020, 09:23 AM   #1
gw1500se
Member
 
Registered: Mar 2004
Distribution: Mandriva 2010.0
Posts: 250

Rep: Reputation: 31
cron syntax


I'm trying to run a script on the first Monday of the month. I set up this:

0 1 * * mon [ $(date +%d) -le 07 ] && /usr/local/bin/pi_backup full

Apparently there is something wrong with my syntax because the job does not run and all I get in the cron.log is:

CMD ([ $(date +)

I'm guessing I need to escape the % but I'm not sure why that is necessary.
 
Old 06-12-2020, 09:58 AM   #2
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,340

Rep: Reputation: Disabled
Rather than invoking [ and date to check that it's the first week of the month, why not specify a date range as a crontab parameter:
Code:
0 1 1-7 * mon /usr/local/bin/pi_backup full
(But it would be interesting to know if the "%" sign needs some form of escaping when used in a crontab, and if so, why.)
 
Old 06-12-2020, 10:00 AM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,700

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
Because % is a cron special character.

Quote:
man (5) crontab:

Percent-signs (%) in the command, unless escaped with backslash (\),
will be changed into newline characters, and all data after the
first % will be sent to the command as standard input.
The reason why 0 1 1-7 * mon does not work.
Quote:
Commands are executed by cron(8) when the minute, hour,
and month of year fields match the current time, and when at least one of
the two day fields (day of month, or day of week) matches the current

Last edited by michaelk; 06-12-2020 at 10:09 AM. Reason: add man cron info.
 
Old 06-12-2020, 10:12 AM   #4
gw1500se
Member
 
Registered: Mar 2004
Distribution: Mandriva 2010.0
Posts: 250

Original Poster
Rep: Reputation: 31
Got it. Thanks.
 
Old 06-12-2020, 10:32 AM   #5
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,340

Rep: Reputation: Disabled
Quote:
Originally Posted by michaelk View Post
Because % is a cron special character.
Quote:
man (5) crontab:

Percent-signs (%) in the command, unless escaped with backslash (\),
will be changed into newline characters, and all data after the
first % will be sent to the command as standard input.
Interesting. It seems there are significant differences between the various cron implementations.

For instance, on a system that uses "Dillon's lightweight cron daemon", the page displayed by man crontab does not contain the text above. Which cron implementation was the quote taken from?
Quote:
Originally Posted by michaelk View Post
The reason why 0 1 1-7 * mon does not work.
Quote:
Commands are executed by cron(8) when the minute, hour,
and month of year fields match the current time, and when at least one of
the two day fields (day-of-month and or day-of-week) matches the current
That seems to indicate that the day-of-month and day-of-week fields are evaluated together as an "or" statement.

This, too, appears implementation-specific. From the man crontab page for Dillon's cron:
Quote:
If you specify both a day in the month and a day of week, it will be interpreted as the Nth such day in the month.
 
Old 06-12-2020, 10:36 AM   #6
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,634

Rep: Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965Reputation: 7965
Quote:
Originally Posted by gw1500se View Post
Got it. Thanks.
To further clarify/complicate/muddy things (depending on how you look at it):
I typically paste this into the tops of all my crontab files.
Code:
# Format is as follows. Six fields, with the sixth being a command to run. The first five are                                                                                                                                                                                                                                     
# date/time related. An asterisk means run matching ANY condition                                                                                                                                                                                                                                                          
#                                                                                                                                                                                                                                                                                                                          
# *     *     *   *    *        command to be executed                                                                                                                                                                                                                                                                     
# -     -     -   -    -                                                                                                                                                                                                                                                                                                   
# |     |     |   |    |                                                                                                                                                                                                                                                                                                   
# |     |     |   |    +----- day of week (0 - 6) (Sunday=0)                                                                                                                                                                                                                                                               
# |     |     |   +------- month (1 - 12)                                                                                                                                                                                                                                                                                  
# |     |     +--------- day of month (1 - 31)                                                                                                                                                                                                                                                                      
# |     +----------- hour (0 - 23)                                                                                                                                                                                                                                                                                         
# +------------- min (0 - 59)
...just for reference purposes. Crontabs can take fairly complicated strings, as well as regex'es, such as:
Running a script on the last Friday of the month:
Code:
1 * * * 5 [ $(date +"\%m") -ne $(date -d 7days +"\%m") ] && /path/to/your/script
The $(date +"\%m") -ne $(date -d 7days +"\%m") statement checks to see if the month today is not equal to month next week (7days from now - same day). If they are equal then current day (Friday in our case) is not the last weekday (we specified Friday) of the month. If not, it is the last Friday, so it runs your script.


Running a script on the last DAY of the month:
Code:
05 10 * * * [ `date -d tomorrow +\%d` -eq '01' ] && /path/to/script
No matter what date is the end of the month, the next day is always "01". The time code will kick it off, but the script will only run if tomorrows date is "01". 

You can test things on the command line with:
Code:
echo $(date +"%m") -ne $(date -d 7days +"%m")
...to play with output until you get what you want.
 
Old 06-12-2020, 11:41 AM   #7
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,700

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
vixie-cron

Your correct there are multiple versions i.e fcron, dcron (Dillon's), vixie/cronie and bcron. Without knowing what distribution/version you can not tell but Mandriva was based on Redhat which did/does use vixie/cronie. And the fact the cron log indicated a new line...
 
Old 06-12-2020, 12:32 PM   #8
ehartman
Senior Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 1,674

Rep: Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888
Quote:
Originally Posted by gw1500se View Post
$(date +%d) -le 07 ]
This is a bash expression, NOT a crontab date field.
You can only specify a (fixed) date range in that field, not an expression.
 
Old 06-12-2020, 12:42 PM   #9
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,700

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
cron is run via sh and using date is a legal command in the 6th field.
 
Old 06-12-2020, 01:15 PM   #10
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,340

Rep: Reputation: Disabled
Or to be more specific, any command is legal in the 6th field. Including (in this case) [, which may or may not be a builtin, depending on the shell being used (vixie/cronie allows a user-specified shell).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Strange Cron directories: /var/spool/cron/cron.GfqqGO Woodsman Slackware 4 05-11-2011 02:37 PM
cron.hourly cron.weekly cron.monthly and 0anacron. Are they necessary? glore2002 Debian 2 09-30-2009 08:57 PM
adding a perl script to cron.daily / cron.d to setup a cron job CrontabNewBIE Linux - Software 6 01-14-2008 08:16 AM
cron not working from crontab nor form /etc/cron/cron.d. What did SuSE change? JZL240I-U SUSE / openSUSE 11 01-04-2007 01:57 AM
Can any one plz explain why/what for cron.d, cron.daily, cron.weekly etc are there. mavinashbabu Linux - Newbie 4 09-21-2006 01:50 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 07:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration