I have a python script (script A) that runs multiple sub-processes (running another python script - script B). When I run the script manually, it works fine, but when it is being run using crontab it behaves differently.
To be more specific, my script is limited to 100TB of quota, so script B runs over a tree and produce a text file of size-per-dir. This script is being run multiple times on several dir-trees as a subprocess, and the results are being further analyzed by script A.
When I run manually, both scripts run fine. But when I run it using Cron, script A runs fine but script B produce odd resutls.
Any ideas of why using Cron would affect a python script?
Make sure the crontab you are using is with full path of the .sh file.
And in beginning of your script try to add the following:
. /home/gemapp/.bash_profile
to load all needed items in bash_profile.
The default directory for any scheduled job is user's home dir, not the location of the shell script/program itself.
To mimic the crontab job, you must simulate running your script from user's home dir using "cd ~" command. Run your job using the exact same syntax as in your "crontab -l" output to simulate the error.
In other word, you must simulate running your schedule job from home dir. Once it worked, then you put it into the crontab.
Related
I stumbled on an answer for basically the exact same question, but either I am implementing the solution wrong, the solution is no longer accurate, or some other issue is at play.
Run a python script in virtual environment from windows task scheduler
I used the code from above link, edited for my directories, and copied directly into the task scheduler program/script prompt.
C:\Users\I511843\myenv\activate.bat && python C:\Users\I511843\Desktop\Atom_scripts\test.py
I then set the program to run every time I unlocked the machine. The program simply writes a text file called test.txt containing the text "success!"
The text file populates in the correct directory when I run from the command line, however, the program doe snot execute from the task scheduler.
Did you try putting the commands in a batch file and executing the batch file from task scheduler? Something like below:
C:\Users\I511843\myenv\activate.bat && python C:\Users\I511843\Desktop\Atom_scripts\test.py goes into task.bat file.
In task scheduler, run task.bat from cmd.
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
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.
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
I have a python program that uses the ThreadPool for multithreading. The program is one step in a shell script. When I execute the shell script manually on the command line, the entire flow works as expected. However, when I execute the shell script as a cronjob, it appears that the flow goes to the next steps before the python multithreading steps are completely finished.
Inside the python program, I do call AsyncResult.get(timeout) to wait for all the results to come back before moving on.
Run your program via batch(1) (see the output of the command man batch) as well. If that works OK, but the cron version does not, then it is almost certainly a problem with your environment variable setup. To verify that, run printenv from your interactive shell to inspect your environment there. Then do the same thing inside the crontab (you will just need to temporarily set up an extra cron entry for it). Try setting the variables in your shell script before invoking Python.
On the other hand, if it doesn't work via batch(1) either, it could be something to do with the files that your code has open. Try running your shell script with input redirected from /dev/null and output going to a file:
$ /usr/local/bin/myscript </dev/null >|/tmp/outfile.txt 2>&1
Try setting "TERM=xterm" (or whatever env variable you have, figure out by command 'env' on your terminal) in your crontab.