4

We know the crontab command is used for scheduled tasks in Linux.

I want to write a Python script. Its function is to receive some data (these data are related to crontab setting) and execute a 'crontab' command in order to reset the content of the user's crontab file.

I know how to execute external Linux commands in Python. But when you execute the crontab command (e.g. crontab -u xxx -e), you need to interact with an editor to modify the user's crontab file. (Suppose I don't know where the file is. For new users, crontab will generate a new file anyway. And I don't execute the command as the root user).

So the question is, how can I just execute crontab in Python? Is there any way to avoid interacting with an editor to modify the user's crontab file in Python?

My OS is ubuntu 14.01.

tjeloep
  • 318
  • 1
  • 4
  • 19
liminche
  • 261
  • 1
  • 6
  • 13
  • 1
    See http://stackoverflow.com/questions/89228/calling-an-external-command-in-python?rq=1#92395 for an excellent answer to this question. – Toolforger May 19 '15 at 06:36
  • That is not what I want. I know how to execute linux commands in python. But my situation is different from that. I have re-edited my question. – liminche May 19 '15 at 07:43
  • possible duplicate of [How can I programmatically create a new cron job?](http://stackoverflow.com/questions/610839/how-can-i-programmatically-create-a-new-cron-job) – tripleee May 19 '15 at 09:10

5 Answers5

10

You could use python-crontab.

Installation

sudo -H pip install python-crontab

Concepts

  • A cron is a time-based job scheduler which is related to a user.
  • A job has a command and a comment and is "attached" to a cron.
  • A job is executed by the cron it is attached to at given times.

Code examples

List system cron jobs:

from crontab import CronTab
cron = CronTab(tabfile='/etc/crontab', user=False)  # system users cron
# cron  = CronTab(user=True)  # current users cron
# cron  = CronTab(user='username')  # other users cron
for job in cron:
    print(job)

Create a new job:

job = cron.new(command='/foo/bar', comment='SomeID')

Enable / disable job:

job.enable()
job.enable(False)

Find an existing job by comment:

iter = cron.find_comment('ID or some text')

Remove Items::

cron.remove( job )
cron.remove_all('echo')
cron.remove_all(comment='foo')
cron.remove_all(time='*/2')

Clear entire cron of all jobs::

cron.remove_all()
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
  • 1
    How to list all existing crons (without using regex or names)? – 0xc0de Feb 23 '21 at 04:44
  • How to modify a old job? job.command='new-cmd' ? – CS QGB Jan 11 '23 at 12:34
  • @0xc0de I'm not sure if this functionality was added after your question, but [per the documentation](https://gitlab.com/doctormo/python-crontab/), you can do something like this to get all existing jobs: `from crontabs import CronTabs; for cron in CronTabs(): print(repr(cron))`. Another alternative is: `jobs = CronTabs.all()`. All jobs are added to a `CronTab` object which can further be used as documented per the project. – Karthic Raghupathi May 13 '23 at 16:51
4

As you want it in Python, you can do "something" like this:

import os;
...
cur_cron = os.popen('crontab -l > current_crontab.txt');
cur_cron.read();
cur_cron.close();
fopen_cron = file('current_crontab.txt', 'a');
fopen_cron.write("\n### Comment here if you like");
fopen_cron.write("\n* * * * * Put your command here");
fopen_cron.close();

Hopefully it helps.

tjeloep
  • 318
  • 1
  • 4
  • 19
3

With Vixie crontab, you could do something like this (obviously you could check for errors and so on):

import subprocess

cron_in = subprocess.Popen(['crontab', '-l'],
    stdout=subprocess.PIPE)
cur_crontab, _ = cron_in.communicate()
# new_crontab = do_my_magic(cur_crontab)
cron_out = subprocess.Popen(['crontab', '-'],
    stdin=subprocess.PIPE)
cron_out.communicate(input=new_crontab)
petre
  • 1,485
  • 14
  • 24
0

You could/should first dump your current crontab with crontab -l, edit it the way you want (e. g. add some lines, or modify) and then install the new one.

This usually works with crontab <filename>, but should as well work with crontab - and then piping the new contents into the process's stdin.

glglgl
  • 89,107
  • 13
  • 149
  • 217
0

If all you want to do is reset the content of user crontab file , then just remove the crontab file (or overwrite with your default) , and reload the cron service .

Alex
  • 5,759
  • 1
  • 32
  • 47