Crontab in Python creates cron job, but doesn't run script - python

Not sure what I'm doing wrong whether it's the code, the directory, or something else. Please help!
from crontab import CronTab
my_cron = CronTab(user='bgoldberg')
job = my_cron.new(command='python /Users/bgoldberg/PythonScripts/FunStuff/writeDate.py')
job.minute.every(1)
my_cron.write()
And here's the writeDate.py script:
import datetime
with open('dateInfo.txt','a') as outFile:
outFile.write('\n' + str(datetime.datetime.now()))
The writeDate.py script just writes the current timestamp to a txt file and it works fine when run separately. When I run python scheduleCron.py, it runs without error but it seems that it's not running the writeDate.py script because no txt file is created. When I enter crontab -l it correctly shows the job that was created: ***** python /Users/bgoldberg/PythonScripts/FunStuff/writeDate.py
Not sure what I'm doing wrong...

This is a cron "gotcha". Cron uses the command
python /Users/bgoldberg/PythonScripts/FunStuff/writeDate.py
which you expect to write to your current working directory, but cron will write to /var/log/syslog or some variation of this by default. It is trying to write to some place you don't have the permissions to (but it won't die), so you need to specifiy the absolute path of your output file.
changing your line in writeDate.py to write to an absolute path:
with open('/Users/bgoldberg/dateinfo.txt', 'a') as outFile:
will solve your problem.

Related

Cronjob not running on Python and Mac

I am trying to test a simple cronjob and when I check if the cronjob has executed, it shows that it has but no file is being created as part of the task.
I have the following script, testjob.py which needs to be executed:
#!/usr/bin/env python3
import datetime
with open('testcron.txt', 'a') as outfile:
outfile.write('\n' + str(datetime.datetime.now() + 'myname'))
This is the cronjob:
#!/usr/bin/env python3
from crontab import CronTab
my_cron = CronTab(user='myname')
job = my_cron.new(command = 'python /Users/myname/Desktop/customers/cronjob/testjob.py')
#schedule job to run every 2 minutes
job.minute.every(1)
my_cron.write()
How can I troubleshoot this?
link to image with my crontab running via crontab -e: https://i.stack.imgur.com/pj9Pt.png
You can set up a cron job via crontab -e, which is much better than creating a python script to create a cron job. But anyways.
You can first troubleshoot by actually running your python script and seeing if there are any errors, and if the file is even created.
make sure the user for that cron job has the right permissions to execute the script.
try executing the command: python /Users/myname/Desktop/customers/cronjob/testjob.py directly from your terminal.
Judging from your response, the reason why its not working is because your script isn't able to open the text file.
When you're executing the script via: python /Users/myname/Desktop/customers/cronjob/testjob.py, the location of your text file "testcron.txt" depends entirely on where you are executing the script from.
So basically, unless "testcron.txt" is located in the same path / directory from where you are executing the script, its not going to work.
You can fix this by changing your cron tab to first navigate to where your text file is, and then run the python script.
For example, if your "testcron.txt" file is located in /Users/myname/Desktop/customers/cronjob/ then write your cron job as:
cd /Users/myname/Desktop/customers/cronjob && python ./testjob.py
You can instead of running the cron job with the python command run it like a shell script.
testjob.py:
#!/usr/bin/env python3
import datetime
with open('testcron.txt', 'a') as outfile:
outfile.write('\n' + str(datetime.datetime.now() + 'myname'))
Cronjob:
#!/usr/bin/env python3
from crontab import CronTab
my_cron = CronTab(user='myname')
job = my_cron.new(command = '/Users/myname/Desktop/customers/cronjob/testjob.py')
#schedule job to run every 2 minutes
job.minute.every(1)
my_cron.write()
Make sure you run chmod a+x /Users/myname/Desktop/customers/cronjob/testjob.py first to make the python executable.

Why doesn't Crontab run the command inserted by python script?

I am trying to modify the crontab of the root user through a script of python (main.py).
This script will open the crontab for root user and will modify it inserting a new command to call single.py with a parameter. The command used is not the problem as I have run it from the command line and it works. When I run the main.py script I can see the new entry when I run the crontab -l command. Everything looks correct but it does not work when is the time (nothing has been executed).
Doing some checks, if I execute the crontab -e command and I insert the command manually; when I save and close it; it shows: **crontab: installing new crontab** and then it works.
main.py:
fname = "/var/spool/cron/crontabs/root"
f = open(fname,"w+")
f.write("24 19 16 01 * python /home/pi/single.py 2087111972\n")
f.close() # save and close cron file
BTW: As this script has to be recursive (it will call itself for rescheduling its execution by modifying the crontab), is there anyway to apply the changes on crontab through the script?

python script won't run at startup ubuntu

I try to run my python scrip at startup but it doesn't work.
Here is my python script(doesn't work):
#!/usr/bin/env python
import paho.mqtt.publish as publish
from datetime import datetime
t = str(datetime.now())
print t
with open("/home/james/mqtt/log.txt", "a+") as f:
f.write("it works " + t + "\n")
Here is my python script(works):
#!/usr/bin/env python
from datetime import datetime
t = str(datetime.now())
print t
with open("/home/james/mqtt/log.txt", "a+") as f:
f.write("it works " + t + "\n")
Here is my rc.local files(also try crontab and setting up service in /ect/init.d):
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# /bin/mqtt_test.py &
# mosquitto_sub -t "mqtt"
/home/james/mqtt/script.sh
# /etc/mqtt/mqtt_test.py
exit 0
It look like by importing paho.mqtt.publish can make my script stop working, I am new to Linux, I have no idea why. Can someone help me out? Thanks for your help.
Ubuntu 16.04
Let me know if you need more info.
I have faced this problem myself. For me the problem was path. I could get it working by using a shell script to launch a python script and launch the shell script from crontab.
Here is my launcher.sh. You may not use sudo if you do not want. home/pi/record_data is the path where my file resides.
cd /
cd home/pi/record_data
sudo python record_video.py
In this case record_video.py is the python file I want to run at startup. In the crontab edit, I added this line below.
#reboot sh /home/pi/record_data/launcher.sh &
Do try this out if it work for you :) Good luck.
I have not got the logging the error into files working yet though.
it looks to me like you need to set/change the write permissions of the file before your python scrypt do this:
f.write("it works " + t + "\n")
for you is working because (maybe you are the owner of the file).
typical linux file permission is described as:
do use the chmod with the property flags, so linux has the rights to write the file too, please refer to the ubuntu help :)

Crontab - Python Script Runs, sends output to mail, but doesn't write to file

I have a job that I have set to run every 5 minutes. I confirm that it indeed runs by running:
grep CRON /var/log/syslog
It shows that it is running the exact command I need it to run 'python3 /root/foofolder/foo.py R'
Dec 29 23:05:01 fooserver CRON[9306]: (root) CMD (python3 /root/foofolder/foo.py R)
It sends the output to mail. I read the mail and output looks as if I was running it in terminal, exactly as I need. The script is supposed to write out to a file. It fails to do so. Running the script in the command line writes the file just fine. I've given the .py file +x permissions and added
#!/usr/bin/python
to the beginning of the .py script. Is there anything else I am missing?
Try using absolute paths and/or os.chdir to a well-known location early in your script (before opening the file).

Crontab Python Script Execution (Can't find settings config file)

My Crontab -l
# m h dom mon dow command
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
00 8,20 * * * python /home/tomi/amaer/controller.py >>/tmp/out.txt 2>&1
My controller.py has config file settings.cfg also it uses other script in the folder it's located (I chmoded only controller.py)
The error
1;31mIOError^[[0m: [Errno 2] No such file or directory: 'settings.cfg'
I have no idea how to fix this? Please help me?
Edit: The part that read the config file
def main():
config=ConfigParser.ConfigParser()
config.readfp(open("settings.cfg"),"r")
As I initially wrote in my comment, this is because you are using relative path to the current working directory. However, that is not going to be the same when running all this via the cron executable rather than the python interpreter directly via the shebang.
Your current code would look for the "settings.cfg" in the current working directory which is where the cron executable resides, and not your script. Hence, you would need to change your code logic to using absolute paths by the help of the "os" built-in standard module.
Try to following line:
import os
...
def main():
config = ConfigParser.ConfigParser()
scriptDirectory = os.path.dirname(os.path.realpath(__file__))
settingsFilePath = os.path.join(scriptDirectory, "settings.cfg")
config.readfp(open(settingsFilePath,"r"))
This will get your the path of your script and then appends the "settings.cfg" with the appropriate dir separator for your operating system which is Linux in this particular case.
If the location of the config file changes any time in the future, you could use the argparse module for processing a command line argument to handle the config location properly, or even without it simply just using the first argument after the script name like sys.argv[1].
Your code is looking for settings.cfg in its current working directory.
This working directory will not be the same when cron executes the job, hence the error
You have two "easy" solutions:
Use an absolute path to the config file in your script (/home/tomi/amaer/config.cfg)
CD to the appropriate directory first in your crontab (cd /home/tomi/amaer/ && python /home/tomi/amaer/controller.py)
The "right" solution, though, would be to pass your script a parameter (or environment variable) that tells it where to look for the config file.
It's not exactly good practice to assume your config file will always be lying just next to your script.
You might want to have alook at this question: https://unix.stackexchange.com/questions/38951/what-is-the-working-directory-when-cron-executes-a-job

Categories