Skip to main content

How to Manage Cron Jobs Using Python

Cron is a powerful Unix/Linux utility that allows you to schedule scripts, commands, and applications to run automatically at specified intervals. The scheduled tasks are stored in a file called the crontab (cron table). Cron jobs are widely used in production environments for tasks like scraping data, updating databases, generating reports, cleaning logs, and sending automated emails.

While you can manage cron jobs directly from the command line, the python-crontab library lets you create, read, update, and delete cron jobs programmatically from within your Python scripts. This is especially useful when you need to dynamically manage scheduled tasks as part of a larger application.

In this guide, you will learn how cron scheduling works, how to use python-crontab to manage cron jobs in Python, and how to handle common tasks like creating, updating, and removing jobs.

Understanding Cron Schedule Expressions

Cron uses a five-field schedule expression to define when a job should run:

* * * * *
│ │ │ │ │
│ │ │ │ └── Day of the week (0-7, where 0 and 7 are Sunday)
│ │ │ └──── Month (1-12)
│ │ └────── Day of the month (1-31)
│ └──────── Hour (0-23)
└────────── Minute (0-59)

Common Schedule Examples

ExpressionMeaning
*/2 * * * *Every 2 minutes
0 */8 * * 1-5Every 8 hours, Monday through Friday
0 4 * * *Every day at 4:00 AM
0 0 1 * *First day of every month at midnight
* * * 1,2 *Every minute in January and February
30 9 * * 1Every Monday at 9:30 AM

Installing python-crontab

Install the library using pip:

pip3 install python-crontab

Then import it in your Python script:

from crontab import CronTab

Essential Crontab Commands

Before working with Python, here are the key command-line tools for managing cron jobs:

CommandDescription
crontab -lList all cron jobs for the current user
crontab -eOpen the crontab file in an editor
crontab -rRemove all cron jobs for the current user
Be careful with crontab -r

Running crontab -r deletes all cron jobs for the current user without confirmation. There is no undo. If you want to remove only specific jobs, use crontab -e to edit the file manually, or use the python-crontab library for targeted removal.

Creating a Job Script

Before scheduling a cron job, you need a script for it to execute. Here is an example script that logs memory usage to a file:

freeMemory.py
import subprocess
from datetime import datetime

command = 'free'

with open('/home/user/memoryInfo.txt', 'a') as output_file:
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
memory_info = subprocess.check_output(command).decode('utf-8')
output_file.write(f'\n--- {timestamp} ---\n{memory_info}')

This script uses the subprocess module to run the Linux free command (which displays memory statistics) and appends the output with a timestamp to a log file.

Creating a Cron Job With Python

Use python-crontab to schedule the memory monitoring script to run every hour:

from crontab import CronTab

# Create a CronTab instance for the current user
scheduler = CronTab(user='your_username')

# Create a new cron job
job = scheduler.new(command='python3 /home/user/freeMemory.py')

# Schedule it to run every hour
job.hour.every(1)

# Write the job to the system crontab
scheduler.write()

print("Cron job created successfully.")

After running this script, verify the job was created:

crontab -l

Output:

0 * * * * python3 /home/user/freeMemory.py

Scheduling Options

The python-crontab library provides intuitive methods for setting schedules:

# Every 20 minutes
job.minute.every(20)

# Every 6 hours
job.hour.every(6)

# Every day (at midnight)
job.day.every(1)

# Every Monday
job.dow.on('MON')

# Specific time: 4:30 AM daily
job.hour.on(4)
job.minute.on(30)

# Using a raw cron expression
job.setall('0 */8 * * 1-5') # Every 8 hours, Mon-Fri
Adding comments to identify jobs

Always add a comment to your cron jobs. This makes them easy to find, update, and delete later:

job = scheduler.new(command='python3 /home/user/freeMemory.py')
job.set_comment("Memory monitoring job")
job.hour.every(1)
scheduler.write()

Updating an Existing Cron Job

To modify an existing job, search for it by its comment (or command), update the schedule, and write the changes:

from crontab import CronTab

scheduler = CronTab(user='your_username')

# Find and update the job by its comment
for job in scheduler:
if job.comment == 'Memory monitoring job':
# Change from every hour to every 2 minutes
job.minute.every(2)
print(f"Updated job: {job}")

# Save changes
scheduler.write()

Verify the update:

crontab -l

Output:

*/2 * * * * python3 /home/user/freeMemory.py # Memory monitoring job

Listing All Cron Jobs

You can programmatically list all cron jobs for a user:

from crontab import CronTab

scheduler = CronTab(user='your_username')

print("Current cron jobs:")
for job in scheduler:
print(f" Schedule: {job.slices} | Command: {job.command} | Comment: {job.comment}")

Output:

Current cron jobs:
Schedule: */2 * * * * | Command: python3 /home/user/freeMemory.py | Comment: Memory monitoring job

Removing Cron Jobs

Remove a Specific Job by Comment

from crontab import CronTab

scheduler = CronTab(user='your_username')

# Remove jobs matching a specific comment
scheduler.remove_all(comment='Memory monitoring job')
scheduler.write()

print("Job removed successfully.")

Remove a Specific Job by Command

scheduler.remove_all(command='python3 /home/user/freeMemory.py')
scheduler.write()

Remove All Jobs

scheduler.remove_all()
scheduler.write()
warning

remove_all() without arguments removes every cron job for the user. Always double-check before calling it, or use filtered removal with comment or command parameters.

Enabling and Disabling Jobs

You can temporarily disable a job without deleting it, and re-enable it later:

from crontab import CronTab

scheduler = CronTab(user='your_username')

for job in scheduler:
if job.comment == 'Memory monitoring job':
# Disable the job
job.enable(False)
print(f"Job enabled: {job.is_enabled()}") # False

# Re-enable the job
job.enable(True)
print(f"Job enabled: {job.is_enabled()}") # True

scheduler.write()

Checking Job Validity

You can verify whether a cron job ran successfully by checking the system log:

grep freeMemory.py /var/log/syslog

Or in Python:

from crontab import CronTab

scheduler = CronTab(user='your_username')

for job in scheduler:
if job.comment == 'Memory monitoring job':
# Check if the schedule is valid
print(f"Is valid: {job.is_valid()}")

# Get the schedule description
print(f"Schedule: {job.description()}")

Complete Example: Full Cron Job Lifecycle

Here is a complete script demonstrating the creation, listing, updating, and removal of a cron job:

from crontab import CronTab

USER = 'your_username'
COMMAND = 'python3 /home/user/freeMemory.py'
COMMENT = 'Memory monitoring job'


def create_job():
scheduler = CronTab(user=USER)
job = scheduler.new(command=COMMAND)
job.set_comment(COMMENT)
job.hour.every(1)
scheduler.write()
print(f"Created: {job}")


def list_jobs():
scheduler = CronTab(user=USER)
print("\nAll cron jobs:")
for job in scheduler:
print(f" {job}")


def update_job():
scheduler = CronTab(user=USER)
for job in scheduler:
if job.comment == COMMENT:
job.minute.every(30)
print(f"\nUpdated: {job}")
scheduler.write()


def remove_job():
scheduler = CronTab(user=USER)
scheduler.remove_all(comment=COMMENT)
scheduler.write()
print(f"\nRemoved all jobs with comment: '{COMMENT}'")


if __name__ == '__main__':
create_job()
list_jobs()
update_job()
list_jobs()
remove_job()
list_jobs()

Output:

Created: 0 * * * * python3 /home/user/freeMemory.py # Memory monitoring job

All cron jobs:
0 * * * * python3 /home/user/freeMemory.py # Memory monitoring job

Updated: */30 * * * * python3 /home/user/freeMemory.py # Memory monitoring job

All cron jobs:
*/30 * * * * python3 /home/user/freeMemory.py # Memory monitoring job

Removed all jobs with comment: 'Memory monitoring job'

All cron jobs:

Common Mistakes and How to Avoid Them

Mistake 1: Forgetting to Call write()

# ❌ Job is created in memory but never saved to the system
job = scheduler.new(command='python3 script.py')
job.hour.every(1)
# Missing: scheduler.write()

Fix: Always call scheduler.write() after creating or modifying jobs.

Mistake 2: Using Relative Paths in Commands

# ❌ Cron runs in a minimal environment: relative paths may not resolve
job = scheduler.new(command='python3 script.py')

Fix: Always use absolute paths for both the interpreter and the script:

# ✅ Absolute paths
job = scheduler.new(command='/usr/bin/python3 /home/user/script.py')

Mistake 3: Not Setting Environment Variables

Cron jobs run with a minimal environment. If your script depends on environment variables like PATH, HOME, or custom variables, they may not be available.

Fix: Set them explicitly in the cron job or within your script:

job = scheduler.new(
command='export PATH=/usr/local/bin:$PATH && python3 /home/user/script.py'
)
info

The python-crontab library works on Linux and macOS. On Windows, cron is not available: use Windows Task Scheduler or libraries like schedule or APScheduler for similar functionality.

Conclusion

The python-crontab library provides a clean, programmatic interface for managing cron jobs directly from Python. You can:

  • create new jobs with flexible scheduling options
  • update existing jobs by searching with comments or commands,
  • remove specific or all jobs,
  • enable/disable jobs without deleting them.

Always use absolute paths in your cron commands, add comments to identify jobs, and remember to call write() to persist your changes.

This approach is far more maintainable than manually editing crontab files, especially when managing scheduled tasks as part of a larger Python application.