Difference between revisions of "Crontab"

From DreamHost
Jump to: navigation, search
m (Added lynx -dump example and explanation)
(dreamhost cron character limit explained)
Line 55: Line 55:
  # The following line will send cronjob output to your user
  # The following line will send cronjob output to your user
== Cronjob character limit ==
Dreamhost's cron web interface states a limit of 1000 characters in a cronjob. What's not explained is that is a limit for the whole file, not just the user input. The real limit is somewhere between 600 and 800 characters. Violating the limit results in this warning:
<pre style="color: red;">
/bin/sh: -c: line 1: unexpected EOF while looking for matching `''
/bin/sh: -c: line 2: syntax error: unexpected end of file
== Crontab files ==
== Crontab files ==

Revision as of 10:41, 12 May 2008

The instructions provided in this article or section require shell access unless otherwise stated.

You can use the PuTTY client on Windows, or SSH on UNIX and UNIX-like systems such as Linux or Mac OS X.
Your account must be configured for shell access in the Control Panel.
More information may be available on the article's talk page.

The crontab command, found in Unix and Unix-like operating systems, is used to schedule commands to be executed periodically. It reads a series of commands from standard input and collects them into a file known as a "crontab" which is later read and whose instructions are carried out.

Generally, crontab uses a daemon, crond, which runs constantly in the background and checks once a minute to see if any of the scheduled jobs need to be executed. If so, it executes them. These jobs are generally referred to as cron jobs. Cron jobs run as the user who set them up, as though you typed this command into your shell, except with more limited environment settings.

You'll need to enable shell access before you can modify your crontab.

More information is available at the shell prompt, with the following commands (hit q to exit):

man cron
man -a crontab

About cron on DreamHost

Execution Environment

Due to security concerns, DreamHost cron does NOT execute with a normal environment. This means you cannot use bare commands. The following will not work:

* * * * * perl myscript.pl
* * * * * perl /home/myuser/mydomain.com/myscript.pl

This is because the PATH environment variable is simply /usr/bin:/bin, and the SHELL is set to /bin/sh. The cron daemon doesn't know where the perl command is located. You must specify the full path to all commands not in the default PATH, and always specify the full path for files, like so:

* * * * * /usr/local/bin/perl /home/myuser/mydomain.com/myscript.pl

If you have any trouble locating where a command is, you can use the following command:

which command-name


which perl

Will print:


(However, these days we do indeed find perl in /usr/bin,

$ PATH=/usr/bin:/bin which perl|xargs ls -og
-rwxr-xr-x  2 1057324 2007-11-04 23:52 /usr/bin/perl

so maybe the above perl example is dated.)

MAILTO variable requirement

For performance reasons, we are now requiring that all crontabs have a MAILTO variable set. This is because by default cron will email output of your cronjobs to your user, and based on testing and research we've found that most people who have cronjobs set never actually check these emails, causing lots of wasted disk space and also some performance issues under certain conditions.

The MAILTO variable can be set to anything. If you leave it blank it will not email output of your cronjobs. You can set it to your username to have it delivered to your user as usual, or you can specify an external email address. Please note that cron emails *do* factor in to your email sending quota if they are delivered to an external email address.

If you do not have a MAILTO variable set when you go to edit or replace your crontab, our system will ask you where you would like it sent.

man 5 crontab says the value string is not parsed for environmental substitutions, thus MAILTO=$LOGNAME will not work, sorry.


# The following line will disable sending cronjob output via email
# The following line will send cronjob output to someuser@example.com
# The following line will send cronjob output to your user

Cronjob character limit

Dreamhost's cron web interface states a limit of 1000 characters in a cronjob. What's not explained is that is a limit for the whole file, not just the user input. The real limit is somewhere between 600 and 800 characters. Violating the limit results in this warning:

/bin/sh: -c: line 1: unexpected EOF while looking for matching `''
/bin/sh: -c: line 2: syntax error: unexpected end of file

Crontab files


The crontab files are where the lists of jobs and other instructions to the cron daemon are kept. Each user at dreamhost has their own individual crontab files and (often there is a systemwide crontab file at /etc/crontab which is also used but can only be edited by the system administrators).

Crontab files are simple text files that have a particular format. Each line of a crontab file follows a particular format as a series of fields, separated by spaces and/or tabs. Each field can have a single value or a series of values. A single cron job should take up exactly one line, but this can be a long line (more than 80 characters).

Each line has five time and date fields, followed by a command, followed by a newline character (’\n’). A common problem is not including a newline, so hit carriage return (a time or three) at the end. Another common problem is automatic word-wrap breaking up a long line into multiple lines, so make sure your editor doesn't.

Blank lines and leading spaces and tabs are ignored. Lines whose first non-space character is a hash-sign (#) are comments, and are ignored. Note that comments are not allowed on the same line as cron commands, since they will be taken to be part of the command. Similarly, comments are not allowed on the same line as environment variable settings.


There are several ways of specifying multiple values in a field:

  • The comma (',') operator specifies a list of values, for example: "1,3,4,7,8"
  • The dash ('-') operator specifies a range of values, for example: "1-6", which is equivalent to "1,2,3,4,5,6"
  • The asterisk ('*') operator specifies all possible values for a field. For example, an asterisk in the hour time field would be equivalent to 'every hour'.

The slash ('/') operator can be used to skip a given number of values. For example, "*/3" means to skip to every third value. So for example "*/3" in the hour time field is equivalent to "0,3,6,9,12,15,18,21"; "*" specifies 'every hour' but the "/3" means that only the first, fourth, seventh...and such values given by "*" are used.


The first five fields of the line are the date and time field which specify how frequently and when to execute a command.

Field no. Description Permitted values
1 minute 0-59
2 hour 0-23
3 day of the month 1-31
4 month 1-12
5 day of the week 0-7

Note: For day of the week, both 0 and 7 are considered Sunday. The time is based on that of the server running cron.

The sixth and subsequent fields (i.e., the rest of the line) specify the command to be run.


The output from commands is determined by the last entries on the line. By default (i.e. if you don't specify anything at all) regular and error output will be e-mailed to you. According to "man cron," when executing commands, any output is mailed to the owner of the crontab (or to the user named in the MAILTO environment variable in the crontab, if such exists). The MAILTO variable may be set in the crontab file. See Handy Crontab Header below for an example.

cron(8) will look at MAILTO if it has any reason to send mail as a result of running commands in ‘‘this’’ crontab. If MAILTO is defined (and non-empty), mail is sent to the user so named. If MAILTO is defined but empty (MAILTO=""), no mail will be sent. Otherwise mail is sent to the owner of the crontab (assuming it has mail delivery or forwarding).

You can redirect the standard output and the errors wherever you like by using ">". When you use ">" without a number before it, it defaults to "1>", and this the 1st output is the standard (non-error) output. When you use "2>" you are saying what to do with the error output. So, for example, ">/my_file.txt" would redirect standard output to a file called "my_file.txt", and "2>/my_errors.txt" would redirect the errors to a file called "my_errors.txt".


Example 1, this will run a command at 4:10pm, and email you the regular and error output:

10 16 * * * /home/someone/bin/mycoolscript.pl

Example 2, this will run a command at 2:00am on saturday, and only email you errors:

0 2 * * 6 /home/me/weekly/weekly-pruning.sh >/dev/null

Example 3, this will run at midnight on newyears, and not tell you anything:

0 0 1 1 0 /home/you/happy.new.years.pyc >/dev/null 2>&1

In that example I used a special redirection. '2>&1' sends the second output (error output, stderr) to the same place that regular output goes (standard out, stdout). In place of that you could have given anything, such as a error log: 2>/home/me/cron.errors.log, or the bit bucket again: 2>/dev/null.

Note: It may be necessary for you to use two digit minute and hour fields. One user reported as having to do this to get cron to accecpt the entry. For example:

01 02 * * * perl /home/me/awstats

Example 4, this will run a php page called cron.php every hour:

0 * * * * wget http://www.somedrupaldomain.com/cron.php

Example 5, this will run a script every 15 minutes:

*/15 * * * * /usr/local/bin/perl /home/myuser/mydomain.com/myscript.pl

Ecample 6, this will run a script every 30 minutes using curl:

*/30 * * * * /usr/bin/curl -s http://domain.com/send.php 1>&2 &>/dev/null

Additional Perl cron operational notes

Executing a PHP Script with Crontabs

To execute a PHP script using crontabs, you must add this line to the top of the PHP script you want to execute (before the opening <?php declaration), or it will not work:

#!/usr/local/bin/php -q

Note: When using the DreamHost Web Panel Cron Jobs, it appears that it is *not* necessary to include the shebang (#!/usr/local/bin/php -q -- or similar line beginning in #!) line in the PHP script itself! (at least not with PHP5 running as a CGI)

Alternately, you can set up your cron entry like this (pay attention to which version of PHP you're running):

Example: This runs p.php every 10 minutes with 0 output, it is shared-server friendly by utilizing the nice command.

*/10 * * * * /usr/bin/nice -n 19 /dh/cgi-system/php5.cgi /home/user/p.php 1>&2 &>/dev/null

* * * * * /usr/local/php5/bin/php /home/youruser/yourdomain.com/path-to-php5-script.php
* * * * * /usr/local/bin/php /home/youruser/yourdomain.com/path-to-php4-script.php
* * * * * /dh/cgi-system/php5.cgi /home/youruser/yourdomain.com/path-to-php5-script.php
* * * * * /dh/cgi-system/php.cgi /home/youruser/yourdomain.com/path-to-php4-script.php

Perhaps an even better way is simply requesting the public url of the php with wget, curl, GET, lwp-request, links, lynx, etc. A benefit to doing this is your php files won't have to be modified and they will be executed using the same environment and permissions as usual.

* * * * * wget http://yourdomain.com/path-to-php-script.php

The below example (lynx -dump) will actually email the output if setup through the web panel. Furthermore, wget downloads to /home/username/ a copy of the output, thus making a mess of the folder (even making empty files if there is no output)

* * * * * lynx -dump http://yourdomain.com/path-to-php-script.php

Handy Crontab Header

# minute (0-59),
# |      hour (0-23),
# |      |       day of the month (1-31),
# |      |       |       month of the year (1-12),
# |      |       |       |       day of the week (0-6 with 0=Sunday).
# |      |       |       |       |       commands
3       2       *       *       0,6     /some/command/to/run
3       2       *       *       1-5     /another/command/to/run

Shortcut Crontab Header

Instead of the first five fields as above, one of these special strings may be used:

string          meaning
------          -------
@yearly         Run once a year, "0 0 1 1 *".
@annually       (same as @yearly)
@monthly        Run once a month, "0 0 1 * *".
@weekly         Run once a week, "0 0 * * 0".
@daily          Run once a day, "0 0 * * *".
@midnight       (same as @daily)
@hourly         Run once an hour, "0 * * * *".

Editing Crontab

To edit the your crontab you'll have to log in to your server with SSH (read the SSH article to learn how to do this). Once you've sucessfully logged in you can begin issuing commands.

From a file

Create a crontab file using your favorite text editor. Take care to follow the syntax above, one entry per line and end with a new line.

If you prefer, the text file may be uploaded. Just make sure to set your FTP client to do an ASCII transfer.

crontab filename

command line text editor

You can also directly edit your crontab by executing the following command:

crontab -e

This pulls up your crontab file with the default text editor, Nano. You can type away, making sure to properly format your command(s). When you're done press ctrl and o at the same time to save, or write out, the file. Now press ctrl and x at the same time to exit. You should recieve a success message, or you may recieve an error message. It should be noted that all commands must appear on one line. If the command wraps onto a second line cron will think it's two seperate commands.

To check that the change was successful:

crontab -l

To remove your crontab and start fresh:

crontab -r

(note: if you attempt to edit your crontab outside your home directory the save will fail. Go home!)

Having nano read your uploaded text file

First you must upload your text file with all the command lines meeting all the guidelines above within yourdomian.com, then connect to your server shell and once nano starts type Ctrl + R then type the URL that points to your uploaded file:


save your file and exit, you should get a confirmation of success.

Changing your Default editor

If your command is wrapping, or if you'd rather work with a different text editor you can do that. You'll have to edit your .bash_profile file. At the command line type:

nano .bash_profile

This is a hidden file so it won't normally show up in your file list. To set your default text editor to not wrap lines, add the following line to the end of your .bash_profile file.

export VISUAL="nano -w"

Now press ctrl and o at the same time to save, or write out, the file. And press ctrl and x at the same time to exit.

If you're used to pico, use the following in your .bash_profile script to keep it from wrapping lines:

alias pico='pico -w'

The following sets the default editor to vim:

export EDITOR="/usr/bin/vim"

Crontab set up using the control panel

It's even easier to set up and manage cron jobs via our control panel interface (no need to use Telnet/SSH!). Go to (GOODIES > CRON JOBS). It should look something like this:


(the >dev/null is optional and will allow the server to only e-mail you errors.)


(other image a little hard to see)

See also

External Links