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
| Expression | Meaning |
|---|---|
*/2 * * * * | Every 2 minutes |
0 */8 * * 1-5 | Every 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 * * 1 | Every 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:
| Command | Description |
|---|---|
crontab -l | List all cron jobs for the current user |
crontab -e | Open the crontab file in an editor |
crontab -r | Remove all cron jobs for the current user |
crontab -rRunning 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:
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
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()
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'
)
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.