crontab: Command not found when running Python script - python

I wrote a Python script which backs up mongoDB, and it works fine when I test run directly in terminal.
However, I get an error from cron saying mongodump: command not found - although the command mongodump works fine when I run the script directly in terminal.
Contents of crontab -e:
* * * * * cd <path-to-script> && python3 script.py

After looking into the post provided by S3DEV's.
Running the full env path of mongodump into the python script worked.
To get the full path of mongodump, in terminal:
which mongodump
>>/usr/local/bin/mongodump
In my case i am using os.system() in my script.
os.system(/usr/local/bin/mongodump [commands])
instead of
os.system(mongodump [commands])

This is because programs started from cron don't get the environment your login shell uses. In particular, PATH is usually quite minimal. The tried and tested way to run scripts from cron is:
Always use an absolute path to a script in the crontab, say /path/to/script.
The beginning of /path/to/script sets and exports PATH and any other variables needed, e.g. with export PATH=$(/usr/bin/getconf PATH):/usr/local/bin
You can test whether any script would run with a reduced environment with
env -i HOME=$HOME /path/to/script
If that runs ok, it is ready for cron.

Related

Crontab Job Raspberry Python Script Influxdb

This is my /etc/crontab file:
1-59/1 * * * * root python3 /home/pi/HP_AD_HAT1/python/maininfluxdb.py
I would like to get my sensor data exactly every full minute in every hour over the day.
Why is my following code not working. If I run the script manually everything is fine. I also checked twice location and file name.
Thanks for help
I also tried crontab -e instructions..
crontab -e
Updated Answer
In your normal shell/Terminal, run:
type python3
then you'll get the full path to your Python3 interpreter. Use that in your cron job.
Note also that crond doesn't go through the full login and shell setup sequence as when you log in, so if your script relies on paths and aliases, they need to be set up equivalently in cron.
Original Answer
You don't specify cron jobs by creating a file in /etc.
Instead, you define your preferred editor, then run the crontab command like this:
export EDITOR=vi
crontab -e
If you think about it, it has to be this way because each user gets their own crontab so it won't be a single file in /etc.
You can get a list of your cron jobs with:
crontab -l
I finally found the solution, it has to do with the comportment of crontab, when it is executing a script, it is doing so with sudo "user". Therefore pythons libraries must also be installed with "sudo" user : sudo pip3 install and not simply pip3 install as I used to.

Running python file from inside a bash script through cron

I have created a bash script which first activates a python virtual environment, and then runs a python file. When I execute the bash script manually, the python file runs as intended. Bash script code:
sample.sh
#!/usr/bin/env bash
source ./project/bin/activate
python3 /home/abc/project/server/sample.py
However, when I try to run this bash script using cron, the python file does not execute.
cron:
16 12 * * * /home/abc/sample.sh > /home/abc/bulkcat.log 2>&1
When this cron triggers at the specified time, the python file inside my bash script does not run and the log file is empty.
What seems to be wrong with my code?
It might well be the relative path you're using in the source command. Cron will run your script from a different directory, so
source ./project/bin/activate
will likely not be a valid path.
Try
source /home/abc/project/bin/activate
... guessed path based on the full path in your python3 ... line.
Cron writes logs and you can find the error which occured when it tried to execute the task - an answer to this question mentions usual locations where to look for these logs.
Most common issues are:
cron is using sh and not bash ignoring shebang in your script - you can try configuring your cron job like 6 12 * * * /bin/bash /home/abc/sample.sh > /home/abc/bulkcat.log 2>&1
the script not having permission to be executable set - this can be fixed by running chmod 700 /home/abc/sample.sh or chmod 755 /home/abc/sample.sh - the latter should be used only if you want to allow other users to read and execute your script
as mentioned already in another answer, always use absolute paths in cron job as cron might execute your script from other directory than you expect - I'm also using wrapper bash script in such scenarios - I give absolute path to the script in cron job and the first thing the bash script does is cd /desired/work/directory

Cron job can't run bash script (that shells python script requiring xsession) that runs perfectly well from console

I am using dryscrape in a python script. The python script is called in a bash script, which is run by cron. For those who may not be aware, dryscrape is a headless browser (use QtWebkit in the background - so requires an xsession).
Here are the main points concerning the issue I'm having
When I run the python script from the command line, it works
When I run the bash script from the command line, it works too
I figured out that this may have something to do with different environments between my command prompt and when the cron job is running, so I modified my bash script to source my .profile as follows:
#/bin/bash
. /full/path/to/my/home/directory/.profile
python script_to_run.py
This is what my cronjob crontab entry looks like:
0,55 14-22 * * 1-5 /path/to/script.sh >> $(date "+/path/to/logs/\%Y\%m\%d.mydownload.log" )
By the way, I know that the job is being run (I can see entries in /var/log/syslog, and the script also writes to a log file - which is where I get the error message below):
In all cases, I got the following error message:
Could not connect to X server. Try calling dryscrape.start_xvfb()
before creating a session
I have installed the prerequisites, on my machine (obviously - since it runs at the command line). At the moment, I have run out of ideas.
What is causing the script to run fine at the console, and then fail when run by cron?
[[Relevant Details]]
OS: Linux 16.0.4 LTS
bash: version 4.3.46(1)
cron user: myself (i.e. same user at the command prompt)
dryscrape: version 1.0.1
The solution to this was to call the dryscrape.start_xvfb() method before starting the dryscrape session.
Cron user does not have display, so you cannot run any command which requires a display.
You need to modify the python script to do not use any type of display (check carefully, because some python commands, even though they do not open any display , they internally check for this variable).
The best way to test is to ssh into the machine without Display, and check if you can run it from there without erros.

Unable to execute Ruby script in a Python script

I'm having trouble executing a Ruby script with my Python code.
My server has a cron job that is supposed to execute a Python script and a Ruby script. However, the Ruby script has to be executed after the Python one, so I decided to add a line:
os.system("ruby /home/username/helloworld.rb")
at the end of the Python script.
It runs, but I'm getting this error in the log file:
/bin/sh 1: ruby not found
I'm not sure why this is happening; I've tried calling the exact same function in the Python console as well as running the Python script manually, and both work perfectly. In other words, this line of code doesn't work ONLY when the script is triggered by cron.
Is there something else I need to put in my crontab/Python script perhaps?
Cron passes only a very limited number of environment variables to your job. According to the CRONTAB(5) Man Page:
SHELL is set to /bin/sh
PATH is set to /usr/bin:/bin
LOGNAME and HOME are set from the /etc/passwd line of the crontab's
owner.
HOME, PATH and SHELL may be overridden by settings in the
crontab; LOGNAME may not.
So if your ruby executable is not located in either /usr/bin or /bin cron cannot find it by default.
You can a specify PATH within crontab to include your ruby executable though.
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 * * * * python my_ruby_calling_script.py

Cron job calling bash script and python scripts

Okay so I have a bash script that simply downloads a web page, and then I use python to pulls some data out of the downloaded page.
So my bash script is along the lines of
#!/bin/bash
html_file="web_page.html"
wget -O /home/michael/Documents/CS288/homework7/web_page.html http://markets.usatoday.com/custom/usatoday-com/html-mktscreener.asp?exchange=13\&screen=1
python hw_7_2.py $html_file
Now, when I just execute this bash script from the command line it runs fine, the wget runs and then my python script executes, however when I set it up as a cron job the wget will run but the python script never executes.
I have not really set up cron jobs so this I think may be the issue. This is basically what my crontab file looks like
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * michael /home/michael/Documents/CS288/homework7/usatoday_runner.sh
try to replace the cron line with :
* * * * * michael /home/michael/Documents/CS288/homework7/usatoday_runner.sh > /tmp/why_is_this_failing.log 2>&1
the answer may be in the /tmp/why_is_this_failing.log
It's possible that your script doesn't have some environment variables set. When a cron job runs it doesn't have your normal profile information - it doesn't load your .profile/.bashprofile (simpler path, JAVA_HOME, etc) one possible option is to have the script source your .profile etc.
Cron frequently fails because of $PATH/working directory sorts of problems. You're setting the $PATH, but I wouldn't be surprised if neither your bash script nor your python script work if you aren't in the right directory.
Try using more absolute paths and see if that clears things up. Similarly, try running your cron command yourself from / or someplace and see if it works for you.

Categories