22

How do I temporarily disable one or more users' cron jobs? In particular, I do not want to suspend the user's cron rights - merely not fire any of their jobs.

I am on SLES 11 SP2 and SP3 systems

Dinesh
  • 1,291
  • Can't you just use the -u user switch of the crontab command and put a # comment character in front of the jobs to disable for the given user? – Janis Mar 06 '15 at 00:41
  • @Janis then I need to keep track of what the user (there are many) had already commented out, plus the user can go ahead and add another thing in (I am not adding them to /etc/cron.deny). Too much manual work :( – Dinesh Mar 06 '15 at 00:49
  • Dinesh, I (mis-)understood you want a fine-granular control about what you disable. – Janis Mar 06 '15 at 01:00

6 Answers6

14

(Note that this answer was written in the days before systemd. I haven't checked how systemd's version of cron behaves in this scenario.)

touch /var/spool/cron/crontabs/$username; chmod 0 /var/spool/cron/crontabs/$username should do the trick. Restore with chmod 600 and touch (you need to change the file's mtime to make cron (attempt to) reload it).

On at least Debian and probably with Vixie cron in general, chmod 400 /var/spool/cron/crontabs/$username also does the trick, because that implementation insists on permissions being exactly 600. However this only lasts until the user runs the crontab command.

If you want a robust way, I don't think there's anything better than temporarily moving their crontab out of the way or changing the permissions, and temporarily adding them to /etc/cron.deny.

  • Thanks. On my system it is /var/spool/cron/tabs/$username. But it still executes, even after the chmod. – Dinesh Mar 06 '15 at 03:19
  • 1
    After changing the file perms, I also needed to stop/restart cron. I thought its probably because cron might be holding the stuff in memory. So I added touch $username after the chmod. But that didn't help. (btw got your point on cron.deny) – Dinesh Mar 06 '15 at 03:28
  • @Dinesh Indeed you need to update the file's mtime or else cron thinks it hasn't changed and keeps cached information. I noticed this while testing yesterday but forgot to mention it in my answer, sorry about that. – Gilles 'SO- stop being evil' Mar 07 '15 at 00:17
  • If you want to disable for all standard users just: chgrp root /var/spool/cron/crontabs – shrimpwagon Aug 25 '15 at 22:11
  • This did not work for me in Ubuntu 20.04. Needed to sudo systemctl restart cron.service as @Dinesh said. – Fazle Rabbi May 04 '23 at 14:07
  • 1
    @FazleRabbi This answer is from before systemd, so it may not apply to modern Linux systems (apart from the non-systemd holdouts). – Gilles 'SO- stop being evil' May 04 '23 at 18:56
  • @Gilles'SO-stopbeingevil' I see that now. thanks! – Fazle Rabbi May 05 '23 at 07:14
12

How about something like this to disable a user crontab:

crontab -l -u [username] >/tmp/[username].cron.tmp
crontab -r -u [username]

and to re-enable:

crontab -u [username] /tmp/[username].cron.tmp

This has the added advantage that you can run it as that user without needing root (just take the -u parameter away).

9

If you just want to stop all cron jobs entirely for a while -- for example, while doing system maintenance which they might interact badly with -- the commands are normally as follows:

sudo systemctl stop crond.service

and, to resume

sudo systemctl start crond.service

Note however that some systems use cron.service instead of crond.service; you can learn which it is as follows:

$ systemctl list-units --type=service | grep cron

Overkill for the specific question posed, but provides "one-stop shopping" and doesn't require playing with the filesystem or temporary files. Also for small embedded systems (Raspberry Pi, Beagle Bone, etc etc, etc) with a single user account.

Seamus
  • 2,925
1

You can use the following like so:

crondisable
cronenable

crondisable some_other_user
...

The zsh code (put in your .zshrc):

ecerr () {
print -r -- "$@" >&2
}
crondisable() {
        local user="${1:-$(whoami)}"
        local cronpath="/tmp/$user.cron.tmp"
        test -e "$cronpath" && {
        ecerr "There is already a disabled crontab at $cronpath. Remove that manually if you want to proceed."
        return 1
        }
        crontab -l -u $user > "$cronpath"
        crontab -r -u $user
}
cronenable() {
        local user="${1:-$(whoami)}"
        local cronpath="/tmp/$user.cron.tmp"
        test -e "$cronpath" || {
        ecerr "No disabled cron at $cronpath"
        return 1
        }
        crontab -u $user "$cronpath"
        mv "$cronpath" "${cronpath}.bak"
}
HappyFace
  • 1,612
1

You can also use

crontab -l | sed '/^\s*[0-9\*]/s/^/#---inserted-by-my-script---/' | crontab

and for re-activation

crontab -l | sed 's/^\#---inserted-by-my-script---//'| crontab

The first line adds #---inserted-by-my-script--- in front of every line with active crontabs, the second line just removes it again. The problem using a temp copy and then do crontab -r is: you can't use it twice. If you remove your crontab and overwrite the existing temp copy of your crontab accidently with the empty one, you don't have a backup.

sneaky
  • 251
-1

I agree, the path via systemctl is the one to take. On raspberry, toe comands would be

sudo systemctl stop cron.service
sudo systemctl start cron.service
jimmij
  • 47,140
Juergen
  • 11
  • 3
    This will stop the entire cron service. The OP wanted to be able to choose which users' crontabs to disable. – Chris Davies Oct 04 '18 at 10:25
  • @roaima: Your comment is correct of course, but I imagine that some people wind up here after using a search term such as linux suspend cron job temporarily, and some of those that do may find this answer (and the one above) quite useful. I wonder if the question how to temporarily disable all user's cronjobs? would be classified as a duplicate? – Seamus May 06 '21 at 21:31