I have a simple Python script on EC2 to write a text to a file:
with open("/home/ec2-user/python/test.txt", "a") as f:
f.write("test\n\n")
That python script is here:
/home/ec2-user/python/write_file.py
When I run that script manually ('python /home/ec2-user/python/write_file.py') - new text is being written to a file ('/home/ec2-user/python/test.txt').
When schedule same script using Cronjob - no data is being added to a file. My Cronjob looks like this:
* * * * * python /home/ec2-user/python/write_file.py
I verify Cronjob is running and suspecting some ENV parameters are not the same during Cronjob execution (or something else is happening). What could be the case and how to fix it in a simple way?
Thanks.
I recently began using Amazon's linux distro on ec2 instances and after trying all kinds of things for cron all I needed was:
sudo service crond start
crontab -e
This allowed me to set a cron job as "ec2-user" without specifying the user or env variables or anything. For example, this single line worked:
0 12 * * * python3 /home/ec2-user/example.py
I also posted this here.
On crontab
HOME=/home/ec2-user/
* * * * * python /home/ec2-user/python/write_file.py
alternatively (testing purpose)
* * * * * root /home/ec2-user/python/write_file.py
On your write_file.py add shebang (first line)
#!/usr/bin/env python
BONUS: (feel free to ignore) my first response debug method for cron on minute tasks:
import os
while True:
print os.popen('pgrep -lf python').read()
executed from shell will pop out all python modules called by cron. After 60 secs you know whats going on.
it's bette to specify the absolute path of the python interpreter because the command may not be recognized by the system. Or you can add the shebang line to your script #!pathToPythonInterpreter at the first line of your script
make sure that the user who planning the execution of script have the right to read and write to the file
make sure that you are not using the system corntab /etc/crontab to planify because then you have to specify the user who will execute the command.
I hope that this will help you
I've been working (and searching) to get this cron job / python script running for some time now. However, it's obviously not working. I'm not sure how else to troubleshoot why, and I've tried several things I've found here in other SO questions.
path to script: /home/phil/cron_jobs/octoStatus.py
I would like cron to run every minute.
Crontab.txt file:
*/1 * * * * python /home/phil/cron_jobs/octoStatus/octoStatus.py &> octolog.txt
The octolog.txt was to capture the STDOUT and STDERR info. Output of "sudo tail /var/log/cron"
Jul 3 10:20:00 bsd /usr/sbin/cron[83876]: (root) CMD (/usr/libexec/atrun)
Jul 3 10:20:00 bsd /usr/sbin/cron[83877]: (phil) CMD (python /home/phil/cron_jobs/octoStatus/octoStatus.py &> octolog.txt)
Jul 3 10:21:00 bsd /usr/sbin/cron[83903]: (phil) CMD (python /home/phil/cron_jobs/octoStatus/octoStatus.py &> octolog.txt)
Jul 3 10:22:00 bsd /usr/sbin/cron[83934]: (phil) CMD (python /home/phil/cron_jobs/octoStatus/octoStatus.py &> octolog.txt)
It appears to be running each minute as desired. However, the expected results of the script are not occurring. octolog.txt is also not being created. When I manually run the exact statement shown in the cron-log, everything works correctly as expected, and the octolog.txt file is created.
I am running this on FreeBSD, and I went to look at the /var/log/syslog, but it doesn't exist. I'm new to FreeBSD, but I'm not sure that means a lot in this situation, but I thought I'd mention it.
I'm not sure what other info would be helpful, as I'm stuck. Thanks. Phil
First off, to run your script every minute, you don't need */1. Cron runs every minute by default, so:
* * * * * /path/to/command
Next, your redirection may be broken. The bash man page has the &> format listed under "Redirecting Standard Output and Standard Error", so I assume that's what you're trying to do. But FreeBSD's /bin/sh is not bash. So:
* * * * * /path/to/command >/path/to/output.txt 2>&1
This sends stdout to your file, and duplicates stderr to stdout.
This brings us to:
* * * * * python /home/phil/cron_jobs/octoStatus/octoStatus.py > octolog.txt 2>&1
Note also according to man 5 crontab, you can set a MAILTO variable in your crontab file which will direct output/errors from your jobs to an email address.
Beware that the PATH used by cron may not include /usr/local/bin, where python is installed. If your octoStatus.py script includes a "shebang", then you may be able to execute it directly. Otherwise, you will either have to provide the full path to your python binary, or add a PATH variable to your crontab (akin to the MAILTO I mentioned above). In all cases, you can get instructions as to format by reading man 5 crontab.
I would recommend you directly write to file from your python script with append mode.
Also just guessing but I think you should give absolute path to output file as stated in comment something like python home/phil/cron_jobs/octoStatus/octoStatus.py &> /home/phil/cron_jobs/octoStatus/octolog.txt
I have a really simple code with docopt which creates a directory. The program works perfectly like this:
dbb create_dir
I need to run this using crontab in ubuntu 12.04. I used crontab -e and added this line:
0 14 * * * dbb create_dir
which should run the code on 2pm every day. My problem is this doesn't work. I checked
0 14 * * * mkdir test_dir
and it worked. So I thought the problem is not with the cron and as I could run the code without cron, I guess the main problem is the combiniation of these two. Is there any way to fix this? Thanx
So my friend figured it out. When I type "echo $PATH", I get this:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
I added "echo $PATH" to the crontab and the result was:
/usr/bin:/bin
So the paths are not the same. So I had to use
/usr/local/bin/dbb create_dir
instead of dbb create_dir
This question already has answers here:
CronJob not running
(19 answers)
Closed 2 years ago.
My python script is not running under my crontab.
I have placed this in the python script at the top:
#!/usr/bin/python
I have tried doing this:
chmod a+x myscript.py
Added to my crontab -e:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
* * * * * /home/me/project/myscript.py
My /var/log/cron file says:
Sep 21 11:53:02 163-dhcp /USR/SBIN/CROND[2489]: (me) CMD (/home/me/project/myscript.py)
But my script is not running because when I check my sql database, nothing has changed. If I run it directly in the terminal like so:
python /home/me/project/myscript.py
I get the correct result.
This is the myscript.py:
#!/usr/bin/python
import sqlite3
def main():
con = sqlite3.connect("test.db")
with con:
cur = con.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS testtable(Id INTEGER PRIMARY KEY, Name TEXT)")
cur.execute("INSERT INTO testtable(Name) VALUES ('BoB')")
cur.execute("SELECT * FROM testtable")
print cur.fetchall()
if __name__ == "__main__":
main()
Per comments: Yes, /usr/bin/python exists. I can also run the python script directly using just /home/me/project/myscript.py. /usr/bin/python /home/me/project/myscript.py works. So I don't believe this is the cause?
There are a lot of half answers across the internet so I thought I would capture this to save someone else some time.
First, cronjob does a poor job of telling you where this is failing. I recommend sending stderr output to a log file like this:
Crontab Command:
# m h dom mon dow command
* * * * * /path/to/your_file.sh >> out.txt 2>&1
As this is likely running the command as user, check home directory for the log file. Note this script runs every minute which is good for debugging.
The next issue is you probably have a path problem... as script likely is trying to execute from your home directory. This script sets the current directory, echos it to file, and then runs your program.
Try this :
Script File
#!/bin/sh
cd "$(dirname "$0")";
CWD="$(pwd)"
echo $CWD
python your_python_file.py
Hope this saves someone else some debugging time!!!
What happens when you type
/home/me/project/myscript.py into the shell?
Can you explicitly use /usr/bin/python in your crontbb command?
Can you either use an absolute path to your test.db or cd to the correct directory then execute your python script?
This is helpful to have debug statements in your python and log some data. Crontab can be very tricky to debug.
It is possible that the script does not start because it cannot locate the python interpreter. Crontab environment may be very different from the shell environment which you are using. The search paths may be differ significantly.
Also, you test your script by starting the python interpreter explicitly while you expect the crontab to only start the script.
I put this line at the top of my python scripts:
\#!/bin/env python
This line will help locate the interpreter regardless of which directory it is installed in as long as it is in the search path.
It's usually because the python used by crontab is different from the one you use in the shell.
The easiest way to solve this is:
get the python you use in the shell:
$ which python # it may be "python3" or something else
/usr/bin/python
use that specific python in crontab file:
* * * * * /usr/bin/python test.py
Also want to mention that using env -i /bin/bash --noprofile --norc in the shell lets you have the same environment as the one used by crontab, and this is super helpful to debug.
Typically, crontab problems like this are caused by the PATH environment variable being more restrictive/different than what your normal user's PATH environment is. Since your shell uses the PATH environment to find the executable (e.g. /usr/bin/python is found in /usr/bin when you type "python" at a shell prompt), when the PATH is missing common locations, like /usr/bin or /usr/sbin, your cron job will fail. This has bit me many times. The simple fix is just to explicitly set the PATH yourself near the top of your crontab file, before any commands that need it. So, just edit the crontab as usual and add something like this near the top (if your binary is not in one of the below paths, you'll need to add it after a colon):
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
Alternately, just use absolute paths to your binaries and scripts in crontab.
Try this
* * * * * cd <directory_where_python_file_is> && bin/app etc/app_defaults.yaml
There is some path issue with cron. So when you move to directory with python file, cron works like charm!
I'd got the same problem. Despite the fact that the script executed manually was working, in crontab no options mentioned above were working at all. I've moved my script from /home/user/script_directory/ to /opt/scripts/ and it started to work. Possible cause of the problem should be the access (read) permissions to subfolder located in home directory.
Easiest way to handle this is to add your python installation's path to PATH in top of the shell script.
Something like:
#!/usr/bin/env bash
export PATH="{path to your python installation}:$PATH"
python {python_file_name}.py
As #Shargors said you can test it by
env -i /bin/bash --noprofile --norc
If you are using anaconda for python then the path to use will be :
/home/username/anaconda3/bin/python test.py
While the answers here clearly delineate the problem and solution, I wanted to add another answer which helped me.
If your python script is calling a database, then be sure you can connect to the db properly within the cron env (to identify the cron env--> https://askubuntu.com/questions/23009/reasons-why-crontab-does-not-work). I had a file that would run from the shell, but not as a crontab unless I connected to the database as root from within the python script.
Sometimes I am facing same problem. Whatever I try something as advised here, I may not get result.
So I begin to write "trigger" bash script as follow (let's name it trigger.sh):
#!/bin/bash
/full_path/python_script.py
And I am calling trigger.sh from crontab and everything is fine.
EDIT: Of course, don't forget to do following (give execution right):
$chmod +x python_script.py
$chmod +x trigger.sh
I was working on project that includes paramiko lib, when I run the Check_.py from cmdlin it works perfect but when I set the crontab it fails with error no module name paramiko.
So to make it short:
- there were two different python versions installed 3.7 and 2.4, so I used whreris python3 to locate the python path /usr/local/bin/python3.7m so replacing the python with the path will solve the issue.
Example
* * * * * cd /home/MKhair/hlthchk/BR/ && /usr/local/bin/python3.7m /home/MKhair/hlthchk/BR/Check_.py
* * * * * cd [ path-to-the-script-dir] && [path-to-python] [path-to-the-script]
Try to put in your crontab:
* * * * * python /path/to/your/script.py
rather than
* * * * * /path/to/your/script.py
Also the shebang line is #!/usr/bin/env python in some environments. env is an executable, and you have to know where it lives with "$ which env".
Is the cron user (where the script fails) and the terminal user (when the script succeeds) are same ?
Can you redirect the job output to some file as mentioned in Cron Job Log - How to Log?. We could see whether that helps.
This might be helpful for someone. I was having this same issue (or at least a similar issue) and what helped me was to get the path in which Python (Be aware of the version you want to use python, python3, etc...) by running this:
which python3
And then, I replaced python3 for the full path of python3 in my crontab file.
what happens to my script in python that does not run through crontab every minute.
My script has execute permissions and then calls two other scripts in python.
This is the content of my crontab (#crontab -l):
*/1 * * * * /usr/bin/rsm/samplesMonitor.py
Thank you guys.
Check /var/log/syslog for errors.
DIAGNOSTICS
cron requires that each entry in a crontab end in a
newline character. If the last entry in a crontab is
missing a newline (ie, terminated by EOF), cron will
consider the crontab (at least partially) broken. A
warning will be written to syslog.
Update: According to your log message, the script is running but returning an error code. Cron will email you the output, if you have a mail agent installed.
Try either:
install a mail agent, such as: apt-get install exim4
change your cron line to log to file, like so:
* * * * * /usr/bin/rsm/samplesMonitor.py 2>&1 >> /tmp/script.log
Update 2: I re-read your question and it acurred to me that maybe you are running into python import issues. You say that your script calls two other scripts. My suggestion would be to test running your script from /. Python has a default behavior to find imports in the current working directory, so make sure your script can run from any path location.
In the crontab, you can set the starting working directory by calling your script from within another shell process. For example:
bash -c "cd THE_WORKING_DIR;/usr/bin/rsm/samplesMonitor.py"
I believe it should be */1, not *\1.
It should be */1 instead of *\1 (forward slash instead of backslash). Also, make sure the path is correct; there usually are no subdirectories under /usr/bin.
If you want it to run every minute, just do this
* * * * * /usr/bin/rsm/samplesMonitor.py