mirror of
https://github.com/opsschool/curriculum.git
synced 2025-12-06 00:19:45 +01:00
267 lines
9.8 KiB
ReStructuredText
267 lines
9.8 KiB
ReStructuredText
#######
|
|
Crontab
|
|
#######
|
|
|
|
Laziness is considered a virtue in system administration, meaning you should
|
|
figure out ways to avoid having to perform the same task regularly by hand.
|
|
**Cron** to the rescue!
|
|
|
|
.. epigraph::
|
|
|
|
**cron** is the time-based job scheduler in Unix-like computer operating
|
|
systems. **cron** enables users to schedule jobs (commands or shell scripts)
|
|
to run periodically at certain times or dates. It is commonly used to
|
|
automate system maintenance or administration, though its general-purpose
|
|
nature means that it can be used for other purposes, such as connecting
|
|
to the Internet and downloading email.
|
|
|
|
-- `cron - From Wikipedia, the free encyclopedia <http://en.wikipedia.org/wiki/Cron>`_
|
|
|
|
**cron** allows you to run routine jobs on a Unix-based system automatically at
|
|
a specific future time or at regular intervals rather than running such jobs
|
|
manually. Even knowing just the basics of cron is a huge win, as this tool
|
|
increases productivity, saves time and is not prone to human error, i.e.
|
|
forgetting to run a job.
|
|
|
|
What is a "crontab"?
|
|
====================
|
|
|
|
"crontabs" (or *cron tables*) are the way that a user schedules a job to run
|
|
under **cron**. They're composed of the following parts:
|
|
|
|
- *cron expression*: A string that describes the time or times when the command
|
|
should be run
|
|
- *user* (optional): If the crontab is specified in a centralized location
|
|
instead of the user's personal crontab file, this field contains the username
|
|
that the command should be run as. This allows **cron** to run a command as
|
|
you, even if you're not logged in at the time. This field isn't used in a
|
|
user's personal crontab file.
|
|
- *command*: The rest of the line is interpreted as the command that **cron**
|
|
should run at the specified time.
|
|
|
|
"crontab" may also refer to a file containing any number of these cron
|
|
tables, one per line.
|
|
|
|
crontab files are commonly found in a couple of different places:
|
|
|
|
- ``/etc/cron.d``, ``/etc/cron.daily``, ``/etc/cron.hourly``, and so on: System
|
|
crontabs, or crontabs installed by a software package
|
|
- ``/var/spool/cron/<username>``: Users' crontabs; these are created
|
|
and managed with the ``crontab`` command.
|
|
|
|
The ``crontab`` command
|
|
=======================
|
|
|
|
How do I list jobs scheduled to run with **cron**?
|
|
--------------------------------------------------
|
|
|
|
The easiest way to see jobs running regularly on the system (aka "cron jobs")
|
|
is to type:
|
|
|
|
.. code-block:: console
|
|
|
|
|
|
|
|
user@opsschool ~$ crontab -l
|
|
|
|
in the shell. This will show all the cron jobs scheduled to run as the
|
|
current user. For example, if you are logged in as ``jdoe`` and there
|
|
are no cron jobs running the output will be something like:
|
|
|
|
.. code-block:: console
|
|
|
|
jdoe@opsschool ~$ crontab: no crontab for jdoe
|
|
|
|
If there are jobs scheduled to run, there will be a list of lines that looks
|
|
something like this:
|
|
|
|
.. code-block:: console
|
|
|
|
05 12 * * 0 /home/jdoe /home/jdoe/jobs/copy-to-partition
|
|
|
|
How do I schedule a job with **cron**?
|
|
--------------------------------------
|
|
|
|
The way to schedule a new job is to type:
|
|
|
|
.. code-block:: console
|
|
|
|
user@opsschool ~$ crontab -e
|
|
|
|
in the shell. This will open an editor with your personal "crontab" file (or
|
|
an empty file if you don't have any cron jobs already scheduled).
|
|
|
|
Then add a line to the file that looks like this:
|
|
|
|
.. code-block:: console
|
|
|
|
0 * * * * date
|
|
|
|
and save and close the file.
|
|
|
|
The cron job you just created will run the command ``date`` at the top of
|
|
every hour (e.g. at 10:00, 11:00, 12:00, etc.). Depending on how your system
|
|
is configured, it may begin to email you the output of that command each time
|
|
it's run, or it may be saved to a log file somewhere.
|
|
|
|
A more in-depth example
|
|
-----------------------
|
|
|
|
Let's look again at the example from before:
|
|
|
|
.. code-block:: console
|
|
|
|
05 12 * * 0 /home/jdoe /home/jdoe/jobs/copy-to-partition
|
|
|
|
Let's dissect this a bit, as it will help when you're creating your own cron
|
|
jobs. What is this output telling you? It is helpful to know what the fields of
|
|
a "crontab" are. Here's a table with the order of fields, and their values:
|
|
|
|
====== ==== ========== ===== ========= ================
|
|
MINUTE HOUR DAYOFMONTH MONTH DAYOFWEEK COMMAND
|
|
0-59 0-23 1-31 1-12 0-6 filepath/command
|
|
====== ==== ========== ===== ========= ================
|
|
|
|
.. note:: Order matters, and note that the first element is 0 for the minute, hour,
|
|
and day of the week fields, while the day of the month and month
|
|
fields begin at 1.
|
|
|
|
Knowing this, we can see that this "crontab" means:
|
|
|
|
At 12:05 every Sunday, every month, regardless of the day of the month, run the
|
|
command ``copy-to-partition`` in the ``/home/jdoe/jobs`` directory.
|
|
|
|
**Caveat**: entries in your crontab must be one long line; if you try to split it up
|
|
(with the linebreak ``\`` character for example) you will get an error!
|
|
|
|
Let's take another example and create a cron job that checks disk space
|
|
available every minute, every hour, every day of the month, every month, for
|
|
every day of the week, and outputs it to a file named :file:``disk_space.txt``.
|
|
|
|
.. code-block:: console
|
|
|
|
* * * * * df -h > disk_space.txt
|
|
|
|
This would get us what we wanted (``df -h`` is the unix command for checking free
|
|
disk space).
|
|
|
|
Field values can also be ranges. Let's say you want to edit this job to run the
|
|
same command (``df -h``), but instead of running every minute, you only want the
|
|
job to run it in the first 5 minutes of every hour, every day of the month,
|
|
every month, for every day of the week.
|
|
|
|
Running ``crontab -e`` again and changing the line to:
|
|
|
|
.. code-block:: console
|
|
|
|
0-5 * * * * df -h > disk_space.txt
|
|
|
|
will get you what you want.
|
|
|
|
How do I remove a crontab?
|
|
--------------------------
|
|
|
|
Lastly, if you want to remove the command, again type ``crontab -e``, and then
|
|
delete the line with that job in it from the file in your editor.
|
|
|
|
To remove all cron jobs for the current user, type:
|
|
|
|
.. code-block:: console
|
|
|
|
crontab -r
|
|
|
|
What are some common "cron expressions"?
|
|
========================================
|
|
|
|
The "cron expression" syntax can be confusing to understand. Here are some
|
|
common expressions to get you started.
|
|
|
|
- ``* * * * *``: every minute
|
|
- ``0 * * * *``: every hour, on the hour
|
|
- ``0 0 * * *``: every day at midnight server time
|
|
- ``0 0 * * 0``: every Sunday at midnight server time
|
|
- ``*/10 * * * *``: every ten minutes
|
|
- ``0 */4 * * *``: every four hours, on the hour
|
|
|
|
Advanced "crontab"
|
|
==================
|
|
|
|
How do "cron expressions" work?
|
|
-------------------------------
|
|
|
|
Here is the standard "cron expression" cheat sheet [#]_::
|
|
|
|
# .---------------- minute (0 - 59)
|
|
# | .------------- hour (0 - 23)
|
|
# | | .---------- day of month (1 - 31)
|
|
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
|
|
# | | | | .----- day of week (0 - 7) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
|
|
# | | | | |
|
|
# * * * * * command to be executed
|
|
|
|
Put this template at the top of your crontab file so it'll be easy to remember
|
|
what the fields do.
|
|
|
|
Notes on composing good "cron expressions"
|
|
------------------------------------------
|
|
|
|
- If you want to run something every N hours, be sure to specify a minute
|
|
expression (the first number) also; otherwise, the command will be run once a
|
|
minute for the entire hour.
|
|
- Commands run by **cron** won't have all of the configuration and environment
|
|
variables that come from your shell initialization files (like ``.bashrc`` or
|
|
``.zshrc`` or such). In particular, make sure to specify the full path to your
|
|
program if it's not in a commonly-used location like ``/usr/bin``.
|
|
- If you have problems with the syntax, or something isn't working properly, there
|
|
are websites [#]_ that will translate crontab to English, and vice versa. [#]_
|
|
|
|
Modify a specific user's crontab
|
|
--------------------------------
|
|
|
|
The ``crontab`` command can be used to view or modify a specific user's crontab
|
|
file, instead of the current user's crontab file. For instance, if you
|
|
are logged in as ``jdoe`` and you want to edit ``jsmith``'s crontab (and you
|
|
have the permissions to do so), type the following in a shell:
|
|
|
|
.. code-block:: console
|
|
|
|
|
|
jdoe@opsschool ~$ crontab -e -u jsmith
|
|
|
|
This option also combines with the other options we looked at before (``-l`` for
|
|
listing and ``-r`` for removing a user's crontab file).
|
|
|
|
Modifying crontab parameters
|
|
----------------------------
|
|
|
|
With some cron implementations [#]_, you can add shell environment variables to
|
|
the top of a crontab file that affect all of the commands run by those crontabs.
|
|
For example, you could modify the ``PATH``, ``MAILTO``, ``HOME``, or any other
|
|
variable.
|
|
|
|
Cron Output
|
|
-----------
|
|
Output from cron commands can be emailed to the owner of the process using a local SMTP server, like ssmtp or postfix.
|
|
If you'd like the output to be sent to an email different than your ``root@yourhost`` address use the ``MAILTO="your@email"`` expression before the cron command.
|
|
An email will be sent containing the output from STDOUT/STDERR every time the command executes.
|
|
Unfortunately, the email gives no indication of the return status of the process (success or failure) and often leads to a cluttered inbox.
|
|
|
|
.. note:: If your crontab is misconfigured you won't receive an email at all.
|
|
Finding such failures (the lack of an email in your inbox) is hard to detect.
|
|
To save time and avoid these *silent failures*, it is better to use a service that will notify you only on cron failures. [#]_
|
|
|
|
--------
|
|
|
|
Footnotes
|
|
=========
|
|
|
|
.. [#] `"Examples" in cron - Wikipedia, a free encyclopedia <http://en.wikipedia.org/wiki/Cron#Examples_2>`_
|
|
|
|
.. [#] `Crontab to plain English <http://cronchecker.net>`_
|
|
|
|
.. [#] `English to crontab <http://corntab.com/>`_
|
|
|
|
.. [#] `Where can I set environment variables that crontab will use? <http://stackoverflow.com/questions/2229825/where-can-i-set-environment-variables-that-crontab-will-use/10657111#10657111>`_
|
|
|
|
.. [#] `Receive notifications when cron commands fail <https://deadmanssnitch.com/>`_
|