Python script failing from crontab - python

I've gone through multiple threads, but I still can't seem to find my problem.
I'm building a really simple Twitter bot that I'd like to fire every hour, on the hour with a cron job from a Raspberry Pi. Here's my crontab:
PYTHONPATH=/usr/bin/python
MAILTO=*myemail*
00 * * * * /home/username/directory/my_script.py >> /var/log/cron.log
Then the script:
#! /usr/bin/env python
import sys
from twython import Twython, TwythonError
from pymarkovchain import MarkovChain
#TWITTER ACCESS
apiKey = KEY
apiSecret = SECRET
accessToken = TOKEN
accessKey = KEY
#text to pull
text = open('/home/username/directory/text.txt').read()
#Generate database and frequency table
mc = MarkovChain('/home/username/directory/markov')
mc.generateDatabase(text)
tweet = mc.generateString()
api = Twython(apiKey,apiSecret,accessToken,accessKey)
try:
api.update_status(status=tweet)
except TwythonError as e:
print e
The first thing I checked was all of my referenced files to make sure they were absolute references. Then, I checked to make sure my file paths were correct. I'm really stumped here. Running the script from command line with the full path works as expected. Any thoughts are appreciated.

After trying the suggestions above and reading countless articles, I learned that cron has to run as root, not as the user. I checked the logs and saw that the user calling the script was the owner of the file, not root. So, running chmod a+x my_script.py took care of it.
Thanks for all the suggestions - especially those getting the errors to the correct log file.

To debug better, you might want to redirect stderr:
00 * * * * /home/username/directory/my_script.py >> /tmp/cron.log 2>&1
# or
00 * * * * /home/username/directory/my_script.py >> /tmp/cron.log 2>/tmp/cron-error.log
(I also changed the path there to make sure your cron user has permission to write output.)
Another thing you could try is run the script with Python in cron:
00 * * * * python /home/username/directory/my_script.py >> /tmp/cron.log 2>&1

Related

Why does Win 7 make a beep when I run a Python script?

I have seen a few question asking how to make a Python script that makes a beep sound.
This question is not about that.
When I run certain Python scripts Windows 7 makes a beep sound but I want to stop the beep.. or at least understand why it's happening.
Here is a test script - test.py:
#!/usr/bin/python
# importing modules
import os
import time
import datetime
from datetime import datetime
def f_log(strtext):
# In this method try and write to the log file
logFilePath = '/home/osmc/python/pyscripter_file.txt'
ts_local = datetime.now()
ts = ts_local.strftime("%d/%b/%Y %H:%M:%S")
try:
# Check if the logfile exists
if(os.path.isfile(logFilePath)):
# Append the error message to the log file. 'a+' creates the file if it does not exist.
with open(logFilePath, 'a+') as f:
f.write(ts + '\t' + strtext + '\n')
else:
print("Log File does not exist - Creating File now")
with open(logFilePath, 'a+') as f:
f.write(ts + '\t' + 'Log File does not exist - Creating File now' + '\n')
f.write(ts + '\t' + strtext + '\n')
except IOError as e:
# Handle the exception
print("Error Msg")
f_log("Test Script")
print("Hello World")
This script is in a directory on a Raspberry Pi running OSMC... in a folder called /home/osmc/python
I have opened it as a remote file in the Pyscripter IDE and can see ssh://osmc//home/osmc/python/test.py
So this means, the Pyscripter IDE, running on Windows 7, is running the Python script on the remote machine. When I run the script this way I get a beep when it finishes executing.
If I create a crontab to run it in osmc...
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/bin/python
53 22 * * * /usr/bin/python /home/osmc/python/test.py >> out.txt 2>&1
Then the script also gives a beep at the end of execution.
If I run the script from a command line to osmc (from an ssh connection in Putty)
# cd /home/osmc/python
# python test.py
I DO NOT get a beep when it completes.
If I run this next script in Pyscripter (or any other way) it does NOT make a beep.
import sys
print('Python '+sys.version.replace('\n','')+' at '+sys.executable+' on '+sys.platform)
Why do I sometimes get the beep? Something in the Python code in the first script I guess?
Flex
My test Python script writes to a log file. I had that log file open in PyScripter IDE.
PyScripter IDE by design makes a beep to signal a File Change Notification affecting any files open in the IDE. This is what was causing the beep whether I was running the script from within PyScripter or not I was still getting the beep because the script was writing to the file open in PyScripter IDE.
I asked the developer and it is currently not possible to turn off this beep.
Flex

Cron SyntaxError with Selenium Python Script

I'm a beginner trying to write a small Python script that I will run through Cron, but I'm getting a Syntax Error from my Cron output log about the program, although the script works fine running through Terminal.
File "/home/pi/Selenium.py", line 19
clickinput = driver.find_element_by_link_text(f"{date}- File")
^
SyntaxError: invalid syntax
I tried looking up how to do this, and one person with a similar issue changed Cron to run as Bash instead of sh, but when I added SHELL = /bin/bash to the Cron file, nothing happened, and I got the same error. Additionally, when I change the f-string into a non f-string, a "selenium module not found" error gets thrown instead.
Any help figuring out the cause of the error would be appreciated!
Cron command:
PATH = /home/pi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/s$
SHELL = /bin/bash
20 18 * * * /home/pi/Selenium.py > /home/pi/Desktop/backdown.log 2>&1
20 18 * * * env > /home/pi/Desktop/env.output 2>&1
Here is my Python script (minus private info)
#!/usr/bin/env python
import time
from datetime import datetime
from selenium import webdriver
driver = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")
driver.get("website");
searchinput = driver.find_element_by_name('mail')
searchinput.send_keys("email")
searchinput = driver.find_element_by_name("pass")
searchinput.send_keys("password")
searchinput.submit()
date = datetime.today().strftime("%m/%d")
if date.find("0") == 0:
date = date.lstrip("0")
clickinput = driver.find_element_by_link_text(f"{date}- File")
clickinput.click()
(This is my first time posting, so sorry if it's bad)

Python Script doesn´t work when started via other script

I´m currently working on a raspberry pi 4 and wrote a script in python that send a mail with a picture and then rename the file and puts it in another folder.
The script works fine when I start with command
sudo python script.py
but when start it with another script it won´t execute the part with the renaming
Now the question what is my mistake ?
import os
import time
from sendmail import mail
from sendmail import file_rename
from time import sleep
pic = '/home/pi/Monitor/Bewegung.jpg'
movie= '/home/pi/Monitor/Aufnahme.avi'
archiv = '/home/pi/Archiv/'
time = time.strftime('%d.%m.%Y %H:%M')
mail(filename = pic )
file_rename(oldname = pic ,name = 'Serverraum Bild' + time ,format = '.jpg' ,place = archiv )
file_rename(oldname = movie ,name = 'Serverraum Video' + time ,format = '.avi' ,place = archiv )
I see that you are starting the script as a user with sudo privileges.
but when start it with another script it won´t execute the part with the renaming
This makes me suspicious that the caller script does not have the correct permissions to rename/move a file. You can view the permissions of the script with the following command
ls -la callerscript.py

Cron job with django application

I would like to use a cron task in order to delete media files if the condition is True.
Users generate export files stored in the Media folder. In order to clean export files in the background, I have a Cron task which loops over each file and looks if the expiry delay is passed or not.
I used django-cron library
Example:
File in Media Folder : Final_Products___2019-04-01_17:50:43.487845.xlsx
My Cron task looks like this :
class MyCronExportJob(CronJobBase):
""" Cron job which removes expired files at 18:30 """
RUN_AT_TIMES = ['18:30']
schedule = Schedule(run_at_times=RUN_AT_TIMES)
code = 'app.export_cron_job'
def do(self):
now = datetime.datetime.now()
media_folder = os.listdir(os.path.join(settings.MEDIA_ROOT, 'exports'))
for files in media_folder:
file = os.path.splitext(files.split(settings.EXPORT_TITLE_SEPARATOR, 1)[1])[0]
if datetime.datetime.strptime(file, '%Y-%m-%d_%H:%M:%S.%f') + timedelta(minutes=settings.EXPORT_TOKEN_DELAY) < now:
os.remove(os.path.join(os.path.join(settings.MEDIA_ROOT, 'exports'), files))
# settings.EXPORT_TOKEN_DELAY = 60 * 24
I edited my crontab -e :
30 18 * * * source /home/user/Bureau/Projets/app/venv/bin/activate.csh && python /home/user/Bureau/Projets/app/src/manage.py runcrons --force app.cron.MyCronExportJob
Then I launched service cron restart
But nothing as changed. My file is still there. However, it should be removed because his date is greater than now + settings.EXPORT_TOKEN_DELAY
I'm using Ubuntu to local dev and FreeBSD as a production server environment.
EDIT:
I tried some things but crontab doesn't work for the moment.
1) * * * * * /bin/date >> /home/user/Bureau/Projets/app/cron_output
==> It works, so crontab works
2) I ran : python manage.py runcrons in my console
==> It works
3) I ran this script (cron.sh):
source /home/user/.bashrc
cd /home/user/Bureau/Projets/app
pyenv activate app
python src/manage.py runcrons --force
deactivate
==> It works
4) I ran this crontab line :
35 10 * * * /home/user/Bureau/Projets/app/utility/cron.sh
==> Service restarted at 10h32, I waited until 10h38 : nothing !

Sqlite python - attempt to write a read only database

I have a simple python script that puts data in a database. Both the script and
the database have owner www-data. When I run sudo python and write the
commands one by one it works, but if I run python monitor.py or sudo python monitor.py it doesn't work; it says, "attempt to write a read only database".
This is my script: (it receives data from arduino)
from serial import Serial
from time import sleep
import sqlite3
serial_port = '/dev/ttyACM0';
serial_bauds = 9600;
# store the temperature in the database
def log_light(value):
conn=sqlite3.connect('/var/db/arduino.db')
curs=conn.cursor()
curs.execute("UPDATE sensor1 set status = (?)", (value,))
# commit the changes
conn.commit()
conn.close()
def main():
s = Serial(serial_port, serial_bauds);
s.write('T');
sleep(0.05);
line = s.readline();
temperature = line;
s.write('H');
sleep(0.05);
line = s.readline();
humidity = line;
s.write('L');
sleep(0.05);
line = s.readline();
light = line;
log_light(light);
if __name__=="__main__":
main()
It sounds like a permission problem. Write access is granted only to the user, which is root. You need to change the user to be directly yourself, not root. You can do this using chmod on many *nix systems.
You could also gove write access to anyone in the group.

Categories