20

I am using crontab for the first time. Want to write a few very simple test cron tasks, and run them.

$crontab * * * * * echo "Hi"

doesn't produce anything.

crontab */1 * * * * echo "hi"

says */1: No such file or directory.

Also, how do I list the currently running cron tasks (not just the ones I own, but ones started by other users such as root as well).

And how do I delete a particular cron task?

xyz
  • 2,991

7 Answers7

28

You can't use crontab like that. Use man crontab to read about the correct way of calling this utility.

You'll want to use crontab -e to edit the current user's cron entries (you can add/modify/remove lines). Use crontab -l to see the current list of configured tasks.

As for seeing other user's crontabs, that's not possible without being root on default installations. See How do I list all cron jobs for all users for some ways to list everything (as root).

Note: be very careful when you use shell globbing characters on the command line (* and ? especially). * will be expanded to the list of files in the current directory, which can have unexpected effects. If you want to pass * as an argument to something, quote it ('*').

Mat
  • 52,586
  • so I do crontab -e and in editor I put entry /1 * * * echo "hi" and when I save this file, I see the message that crontab: installing new crontab. but I don't see the hi messages appearing on screen. What am I missing now? thanks. – xyz Sep 23 '11 at 10:20
  • 2
    crontab's output will never go to your "screen". From the POSIX man page for crontab: "If standard output and standard error are not redirected by commands executed from the crontab entry, any generated output or errors will be mailed, via an implementation-dependent method, to the user." – Mat Sep 23 '11 at 10:23
  • 1
    The job's output will be sent to the job owner's local mail box. (Running mail from the command line should access your local mail box, if configured.) To see the 'hi' in graphic environment, you could set the task as: * * * * * export DISPLAY=:0; xmessage 'hi'. – manatwork Sep 23 '11 at 10:30
  • @manatwork You may also need XAUTHORITY, which may not be easy. – derobert Sep 20 '12 at 21:53
  • This answer would be much more useful if the first line were removed entirely. It's not nice to effectively start your answer with RTFM, even if you do then go on to answer properly too. – Mark Booth Apr 20 '22 at 10:09
15

There are two ways of editing one's crontab:

  1. interactively, using crontab -e, which will open the crontab in the editor specified by $VISUAL or $EDITOR, or

  2. non-interactively, using crontab crontab.txt, which will simply import the crontab entries from the file crontab.txt, replacing the existing active crontab for the current user.

The issue that you have is that you are simply using the crontab command wrong.


The following concerns non-interactive crontab manipulation:

So, to remove particular tasks programmatically, you could do something like

$ crontab -l | grep -v 'PATTERN' >crontab.txt && crontab crontab.txt

where PATTERN is a regular expression that will match the task(s) that you'd like to remove. Here, crontab -l will give you your current crontab.

Or, if you have entries in a file called crontab-fragment.txt that you want to remove from the active crontab,

$ crontab -l | grep -v -Fx -f crontab-fragment.txt >crontab.txt && crontab crontab.txt

This reads the current crontab and filters out (removes) any line that also occurs in the file crontab-fragment.txt in the current directory (using a full line string comparison). The result is saved to crontab.txt and then loaded from there to replace the current crontab.

To add one or several task, do something like

$ crontab -l | cat - crontab-fragment.txt >crontab.txt && crontab crontab.txt

This is assuming that the file crontab-fragment.txt contains the entries that you would like to add. It reads the current crontab, appends the entries from crontab-fragment.txt to this and creates crontab.txt. The crontab.txt file then replaces the current crontab.

Kusalananda
  • 333,661
3

This is a bit late, but for others looking here. There are easier ways than manipulating the input/output streams with VISUAL and EDITOR.

You can simply write your cron schedule in a file, 1 job per line, and use the command crontab [filename] so you can cat your jobs into filename as part of your script and then finally call crontab at the end if you like.

in fact this is the most common use as man crontab hints by listing it first

3

If you wish to add entries to the crontab by automation or from the command line, you can do (setting the times you wish to have)

echo "* * * * * /yourpath/yourcommand 2>&1 >> /var/log/somelog.log" >> /var/spool/cron/root (or appropriate username)

Then:

service crond reload

to reload the crontabs.

  • 1
    This is unportable; not all unix store the crontab files under /var/spool/cron. A better way would be through the crontab(1) command. – thrig Mar 28 '17 at 22:34
  • 1
    That may be true, but it was to show the principle of how you can do it on a system, and yes, crontab does the trick if you want to add line by line. It was not meant to be an absolute answer, but one if you know where your stuff is, and you need to mass add. Take it for what it is. – Chris Sprucefield Mar 29 '17 at 20:39
2

If you want to modify the crontab interactively, run the command crontab -e, with no other option. This will start an editor on a copy of the crontab; when you exit the editor, the edited copy will become the new crontab. You can control which editor is started through the VISUAL and EDITOR environment variables. To list your crontab, run crontab -l.

If you want to modify the crontab in a script, set VISUAL and EDITOR to the path to a script or to a shell snippet that modifies the supplied file in place. The editor ed is a possibility here, or sed -i if your implementation of sed has this option. If you want to unconditionally add a line, you can use echo … >>. Take care with quoting; if at all in doubt, write a script and pass the name of the script as EDITOR.

script=$(mktemp)
cat <<'EOF' >"$script"
#!/bin/sh
ed -s "$1" <<'EOS'
g/^ *[^= ][^ =]*  *[^= ][^ =]*  *[^= ][^ =]*  *[^= ][^ =]*  *[^= ][^ =]*  *echo "hi"$/d
$a
* * * * * echo "hi"
.
w
q
EOS
EOF
2

Try it with this command:

crontab -e 

then add your cron job:

*/1 * * * * echo "hi"

in that file.

techraf
  • 5,941
1

I would like to highlight the way I describe below even though It has been mentioned before in another comment. I found it extremely useful when adding the entries to a file and then add the file to crontab. That file would contain the two entries below and the file name would be hello-world-crontab.txt.

  • 0 09 * * * echo "Hello world!" >> /home/user/greeting.txt
  • 0 09 * * * python /home/user/greeting.py

Then, I executed the command below to add these entries to the crontab.

  • $ crontab hello-world-crontab.txt

The next step is to verify these entries have been added.

  • $ crontab -l

A brief explanation on what each entry does:

  • This crontab entry writes "Hello world!" into the file /home/user/greeting.txt every day at 9 am.
    • 0 09 * * * echo "Hello world!" >> /home/user/greeting.txt
  • This crontab executes a python file which prints in the command line 'Hello world!' every day at 9 am.
    • 0 09 * * * python /home/user/greeting.py