Is There a Special Restriction on Commands Executed by Cron

Is there a special restriction on commands executed by cron?

You have to escape percent signs with a backslash:

0 0 * * * pg_dump DB_NAME > /path/to/dumps/`date +\%Y\%m\%d`.dmp

From man 5 crontab:

The ‘‘sixth’’ field (the rest of the line) specifies the command to
be
run. The entire command portion of the line, up to a
newline or %
character, will be executed by /bin/sh or by the shell specified in
the
SHELL variable of the crontab file. 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. There is no way to split a single command line
onto
multiple lines, like the shell’s trailing "\".

How is % special in crontab?

The actual problem of your crontab line is not the $() or the backquotes. The problem is the percent sign %. It has a special meaning in crontabs.

From the manpage:

...
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.
...

If you escape the percent sign with \ it should work as expected:

* * * * * echo $(date +\%F) >> /tmp/date.txt

or

* * * * * echo `date +\%F` >> /tmp/date2.txt

both work on my site.

chpasswd is unknown command when called in cronjob?

Converting commentary into an answer.

What is the PATH supplied to your cron job? Where is chpasswd stored? Since the directory where chpasswd is stored is not listed in the path provided by cron, it fails to find it. You get a very limited environment with cron; running anything the least out of the ordinary means great care is required.

Either set PATH more fully in the script run by the cron job, or specify the absolute pathname of the commands that are not in /bin or /usr/bin.

Incidentally, how do you set P for echo to echo it? Doesn't it set the same value each month? Is that wise?

There are numerous other questions on Stack Overflow about difficulties running commands from cron jobs. Amongst others, see Bash script not running in cron correctly and Perl script works but not via cron and Is there a special restriction on commands executed by cron?, to name but three.

Does cron job executing script cancel each other

It is neither. The two tasks overlap, and run at the same time.

Cron jobs don't cancel each other unless they try to lock and access the same files, or the scripts have some other conflicts. You can of course make them cancel each other if you want, though.

The server is none the wiser, and the tasks don't wait for previous executions unless you explicitly add such details, for example, by using flock or pgrep to check for previous executions still running.

The following example entry in cron tab checks if the script is already running, and only runs if the script (cron.sh) is not already running.

* * * * * /usr/bin/pgrep -f /path/to/cron.sh > /dev/null 2> /dev/null || /path/to/cron.sh

Maximum length for cron job

Someone on serverfault answered a similar question - Crontab maximum command length

999 characters.

Just create a bash script and run it instead of having the entire command in crontab.

PHP cli command line safe_mode restriction

At nowadays you can schedule php script execution from UI like this:

plesk schedule cron url php script

In case you still need execute script via command line pay attention that Plesk's PHP binaries are placed in:

# 7.0
/opt/plesk/php/7.0/bin/php
# 5.6
/opt/plesk/php/5.6/bin/php
# 5.5
/opt/plesk/php/5.5/bin/php
# and so on

Original answer:

I know this is a few months old, but for the next person that comes across a problem while using Plesk and cron and PHP, here's the answer.

While Plesk does run cron as ROOT, it also runs PHP by default with safe mode ON, which means that when you setup a cron in Plesk that needs PHP, it's going to have restrictions that you do not experience from the shell or from the web.

So what you do is use the CLI /etc/php.ini option override, like so:

/usr/bin/php -q -d safe_mode=Off /var/www/vhosts/path-to-your-php-file.php

Why is this cron entry executed twice?

Nothing in the description gives reason for it to be executed twice. Look elsewhere.

  • Do two users call it?
  • Is it entered twice?
  • Does it call itself?
  • Does it set in motion conditions for repetition?

If it's a shell script you're executing, have it append whoami and date to a log file. You should be able to dig up the reason.

UPDATE

Type ps -A | grep crond, make sure crond isn't running twice.

Does crontab day of week and day of month must both be matched at the same time?

It means if one of the two conditions is satisfied (can be both, does not need to be)

Note: The day of a command's execution can be specified in the following two fields — 'day of month', and 'day of week'. If both fields are restricted (i.e., do not contain the * character), 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.

source: man 5 crontab

In the examples of the OP, if the day is Wednesday Jan 09 2019, than the crontab:

x x 9 x 2

will execute because it is the nineth day of the month, and

x x 10 x 3

will execute because it is a Wednesday

Setting cron job end time

man 5 crontab is your friend. (Your example does not do what you claim it does; /1 is the default skip and therefore redundant, and that spec therefore runs once per minute due to the leading * instead of 0.)

0 10-15 * * * your command here

(I used 15, because it occurs to me that "between 10 and 4" is an exclusive range so you don't want to run at 16:00.)



Related Topics



Leave a reply



Submit