Python script works when I run it, does nothing in cron. What am I missing?
Ray Alvarez@ruck_n_code
Quick one. Practicing Linux for the transition (ETS in 7 months, SkillBridge after that if it gets approved).
Wrote a Python script that pings a list of hosts and writes the results to a CSV. Works fine when I run it from my home directory. Put it in crontab -e to run every 5 minutes. Nothing. No CSV, no error, nothing.
*/5 * * * * python3 pinger.py
What I checked:
- cron is running (
systemctl status cronsays active) - script is executable, has the shebang
- uses the
requestslibrary, which I installed in a venv in the project folder
Ubuntu 22.04 VM. Good to go on everything else. What am I missing?
Accepted answer
Brother, Jen's right, it's a path thing. Two of em actually.
1. Cron runs with a bare-bones environment. Your venv isn't activated, so python3 is the system Python, which doesn't have requests. The script dies on the import.
2. You never see the error because cron has nowhere to send the output. No mail server on that VM, so it goes in the bit bucket.
Fix both in one line. Absolute paths for everything, and send the output to a log:
*/5 * * * * cd /home/ray/pinger && /home/ray/pinger/.venv/bin/python pinger.py >> /home/ray/pinger/cron.log 2>&1
The cd matters if your script opens hosts.txt or writes results.csv with a relative path. To confirm cron actually fired at all: grep CRON /var/log/syslog
Once that works, look at systemd timers. Output goes to journalctl for free and you can test the unit by hand with systemctl start. That's what we run at work. My 2 cents.
Get the best of #rubber-duck-club weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to commentJen Hayes@night_owl_jen
ray i have no idea but i'm here for moral support 🦉 also i bet it's a path thing, it's always a path thing lol
Accepted answer
Brett Hollister@brett_hsv
Brother, Jen's right, it's a path thing. Two of em actually.
1. Cron runs with a bare-bones environment. Your venv isn't activated, so python3 is the system Python, which doesn't have requests. The script dies on the import.
2. You never see the error because cron has nowhere to send the output. No mail server on that VM, so it goes in the bit bucket.
Fix both in one line. Absolute paths for everything, and send the output to a log:
*/5 * * * * cd /home/ray/pinger && /home/ray/pinger/.venv/bin/python pinger.py >> /home/ray/pinger/cron.log 2>&1
The cd matters if your script opens hosts.txt or writes results.csv with a relative path. To confirm cron actually fired at all: grep CRON /var/log/syslog
Once that works, look at systemd timers. Output goes to journalctl for free and you can test the unit by hand with systemctl start. That's what we run at work. My 2 cents.
Ray Alvarez@ruck_n_code
Copy that. That was it. ModuleNotFoundError: No module named 'requests' sitting in cron.log on the first run. Fixed with the venv python path, CSV populating every 5. Good to go. Thanks Brett.
Brett Hollister@brett_hsv
Squared away. Next drill: break it on purpose and find the problem from the log in under 2 minutes. That's half a job interview right there.
Graham Whitfield@greybeard_graham
Every sysadmin's first cron job fails for exactly this reason. Mine was in 1991 on a Sun box. Welcome to the club. Cheers, G.
JoJo Ramos@jojo_navyvet
Bravo Zulu Ray. Log to a file before you debug anything, that is half of IT. Never too old, never too new.