Schedule a Python script with cron
Run a Python script from cron with explicit paths, a predictable environment, writable logs, and checks for failed or missing executions.
Add a command to your user crontab with crontab -e. Use absolute paths for the interpreter, script, and output file, and test the command as the same user that cron will run it under.
Prepare and test the script
For a cleanup task, start with a dry run so you can inspect the intended files. This example deliberately skips directories and symbolic links:
# /home/user/scripts/cleanup.py
from pathlib import Path
folder = Path("/tmp/temp_files")
dry_run = True
for path in folder.iterdir():
if path.is_symlink() or not path.is_file():
continue
if dry_run:
print(f"Would delete: {path}")
else:
path.unlink()
print(f"Deleted: {path}")
Create and verify the intended folder first. Set dry_run = False only after reviewing the selection. This example is for a controlled directory; checking a path and then deleting it is not race-free if other users can replace entries. Production cleanup should also define age or retention criteria and how partial failures are reported.
Add the schedule
Create a log directory that the cron user can write, then edit that user's crontab:
mkdir -p /home/user/logs
crontab -e
Run every day at midnight:
0 0 * * * /usr/bin/python3 /home/user/scripts/cleanup.py >> /home/user/logs/cleanup.log 2>&1
Replace the example interpreter path with the one your application uses. For a virtual environment, invoke its interpreter directly, such as /home/user/venv/bin/python; activation is unnecessary.
Make the environment explicit
Cron starts a process with a working directory and a limited environment. Do not assume either matches your interactive shell. Use absolute file paths or explicitly change to a known directory before running the command. Set required non-secret configuration deliberately and load credentials from appropriately protected configuration rather than exposing them in diagnostic output.
The shell performs >> logfile 2>&1 before starting Python. If it cannot open the log, the script may never run. Confirm permissions and rotate logs that grow over time.
Read the five schedule fields
| Field | Meaning |
|---|---|
| First | Minute, 0–59 |
| Second | Hour, 0–23 |
| Third | Day of month, 1–31 |
| Fourth | Month, 1–12 |
| Fifth | Day of week; Sunday is commonly 0 or 7 |
*/5 * * * * runs every five minutes, 0 */2 * * * every two hours, and 0 9 * * 1-5 at 09:00 on weekdays. Time-zone and daylight-saving behavior depend on the cron implementation and configuration. Cron also does not automatically prevent a long-running job from overlapping its next scheduled execution; add an appropriate locking policy when overlap is unsafe.
Verify execution and collection
Record the job name, start, completion, and outcome. Check the daemon's logs through the system journal or distribution-specific files such as /var/log/syslog or /var/log/cron. A launch record proves only that cron attempted to start the command, not that the task finished successfully.
Once the logs are collected in Guance, use log detection to investigate failure events. Monitor missing expected completion separately, allowing for the job's schedule and ingestion delays. A missing event may indicate a collection problem; test a manual execution and its end-to-end log delivery first.
FAQ
Why does it work interactively but fail in cron? Compare interpreter, dependencies, working directory, configuration, and permissions. Inspect only the environment fields you need rather than dumping secrets into a shared temporary file.
Can I schedule inside Python? APScheduler or schedule can run work inside an application process. Plan process supervision, restart behavior, persistence, and missed executions. Cron and an in-process scheduler have different failure modes; neither guarantees job success by itself.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan