Crontab not running a Processing script - java

I have a python script that I am running from the command line that does three things
1.) Kills all Processing programs currently running
2.) Runs a new Processing program
3.) Shut downs Raspberry Pi
When running this command from the command line, it works flawlessly. Yet, when calling this Python script using crontab, only the 1st and 3rd processes run correctly. What I want to know is why the 2nd command (running a new Processing program) works when I run the Python script from the command line, but not from a crontab?
Here is my Python script
import os # Use operating system
import subprocess # Use subprocess calls
from time import sleep # Use sleep
from subprocess import call
os.system('sudo killall java')
sleep(5)
child = subprocess.Popen('sudo processing-java --sketch=/home/pi/Desktop/LaserCannonProcessing/LCshutdown --run', shell=True) #
sleep(15)
call("sudo poweroff", shell = True)
and here is my crontab
50 20 * * * sudo /usr/bin/python3 /home/pi/Desktop/Shutdown.py
Does anyone know why crontab can not successfully run the command to run a processing program? If so, is there any way I can fix this and make crontab run that line? Thanks

The cron daemon automatically sets several environment variables. The default path is set to PATH=/usr/bin:/bin.
So if the processing-java command is not present in the cron specified path, you should either use the absolute path to the command or change the cron $PATH variable.
Using shell=True is masking the problem...
E.g.
In [7]: child = subprocess.Popen('bla', shell=True)
/bin/sh: bla: command not found
In [8]: child
Out[8]: <subprocess.Popen at 0x107ac8c50>
You can add some debugging to your script to find out the real issue:
try-except around the subprocess call and shell=True
print the os.environ["PATH"]
check permissions on files (if your process needs to read/write to files)

Related

Shell script that sets LD_LIBRARY_PATH=`pwd` does not work from Java

shell script file directory: /some/location/myShellScript.sh
Properties-Type: shell script (application/x-shellscript)
EDIT
content of shell script:
#!/bin/bash
export LD_LIBRARY_PATH=`pwd`
echo `pwd`
./someExecutable ../input/cfg/test1.ini
The test1.ini is generated one step before in the java code,
it provides settings for some testing, which is done in the background. Then the shell script ends up with the file I need for further processing.
/EDIT
When I am running this shell script on linux terminal in its own directory just with "./myShellScript.sh" it works perfectly fine...
The part my shell script shall be executed:
//Do something before
//Shell scripts creates a file
String cmd = /some/location/myShellScript.sh;
ProcessBuilder pb = new ProcessBuilder(cmd);
Process process = pb.start();
int exitValue = process.waitFor();
System.out.println(exitValue);
//Afterwards I am processing the generated file
When running my java program as an executable .jar file, this process gets not executed and the exitValue is 127, but I don't know why...
I tried many things like:
using the Runtime to exec
adding #!/bin/bash or #!/bin/sh on top of the shell script
adding a "sh" parameter to the process command in form of String[]
In my execution directory, I changed the permission with chmod 755 -R * recursively so every associated library used by the shell script is indeed available (also due to the fact, that I can just execute it on the terminal).
I really tried to find a proper answer on the internet but I wasn't successful.
And no, I cannot just do everything in java, the shell script is mandatory and cannot be replaced in this case.
Thanks in advance for helpful suggestions!
The script you are executing is highly sensitive to its working directory. It uses pwd to set the LD_LIBRARY_PATH and it attempts to execute another program via a relative path to that program, providing a relative path as a command-line argument, as well.
The working directory for an execution of the script has no essential relationship with the directory in which the script resides -- it completely depends on how and in what context the script is launched. For example, you report that the script works as you expect "When I am running this shell script [...] in its own directory." But when you run the script from Java you very likely are not running it with its own directory as the working directory, and that will strongly affect this script's behavior.
One solution would be to hardcode the script's installation path into the script itself, and to express all your paths relative to that:
#!/bin/bash
installation_dir=/path/to/the/script/dir
export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini
It's a bit kludgy to hardcode the path, though. You could further improve it by having the script identify its own directory at runtime:
#!/bin/bash
installation_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini
That's obviously Bash-specific, but you were using bash anyway. Alternatively, if the executable your script launches is also sensitive to its working directory, then perhaps you just want the script to change directory (which will be effective only for the script and processes downstream from it, not for its parent process):
#!/bin/bash
cd "$( dirname "${BASH_SOURCE[0]}" )"
export LD_LIBRARY_PATH=`pwd`
./someExecutable ../input/cfg/test1.ini
The 127 exit status means that a command used in the script is not found.
EDIT
Debug the script, when bash is used, add the line below on the second line:
exec > /tmp/debug.txt 2>&1 ; set -x
After the next attempt, analyze the traces generated into the /tmp/debug.txt file.
OLD INTRO
(the script content was not yet provided)
The Java program which executes the myShellScript.sh script has probably not the same PATH environment variable than the one which is set in your environment when you execute the script manually from a terminal.

How can I configure my program to run in a loop?

How can I configure my Java program to run in a loop? I have written a code in Unix Shell Script and it's working fine.
Here is the code written in unix:
if [ "$1" != "ALL" ]
then
while [ "$i" -le $1 ]
do
java -cp $BATCHCLASSPATH -Dbootstrap.system.propertiespath=/home/wlc1212/15AUNIXDEV/SpringBatch/properties -Dfile.encoding=UTF-8 com.tcs.wstest.Test $FILPATH/$2Input_$i.xml $FILPATH/$2Output_$i.xml $i
i=`expr $i + 1`
done
fi
// $1 can be 1 or 2 or n
Now I want to run it in a same way but in Eclipse. Is there any way to run my program in the same way in Eclipse? How can I set a loop?
In Eclipse Luna and probably other Eclipse versions, an external script can be run by creating a run configuration for it in Run/External Tools/External Tools Configurations. In the latter's window create a new launch configuration with absolute pathname of your external shell such as bash in the Location field and the absolute pathname of your bash script in the Arguments field. The Working Directory field can be whatever is appropriate for your script in case it needs to read or write data to certain files.
This does not have the capability to automatically rerun the script but
you have already coded it with a loop so its not necessary to do that externally.
Another typical way to repeat execution of a script on Unix/Linux systems is to use cron or "at" and both can be configured at user level. This may be preferable in order to run the script at fixed time intervals provided the runtimes will be reasonably bounded. The cron or "at" job could run your java command directly or it could run another script written to check that your java application is not running before launching it again.

shell script runs when executed manually but executes half way through crontab

I have a java service running on a solaris server. I need to kill this service and restart it every night at a specified time. Hence i have set a cron job to do the same. My script works fine when i execute it manually through command line. But when i set it as a cron job, it executes only half way i.e it only kills the process but does not start it. Kindly assist me. Below are the details:
Restart script:
#!/bin/sh
pkill -u peri java 2>> /dev/null
sleep 3
cd /opt/home/peri/utils/jsb
. /opt/home/peri/utils/jsb/pjsb.new
sleep 3
cd /opt/jar
MonitorExt.sh & > /dev/null
Here pkill is killing the java process. The script pjsb.new is the script which is used to start the java process. Also one more script MonitorExt.sh is used to start another java process.
Any help is highly appreaciated!!!!
Thanks in advance
1) under user 'root', check for some cron error messages in /var/cron/log
2) usually when commands/scripts are running fine manually but not in the cron job, it is because some environment variables are not set in the cronjob context.
So you should make sure that all the necessary environment variables which are automatically set in your default shell ($HOME, $JAVA, ...) are actually set when running in a cron job
I usually call a profile script inside the script or in the cronjob line:
15 17 * * * . $HOME/.profile && $HOME/script.sh
3) You should also prefer full paths for all your scripts and commands:
/usr/bin/pkill
/path/MonitorExt.sh
...

Open a new terminal window and execute command in it by java without using bash script

For examples, this is my bash script
osascript -e 'tell app "Terminal"
do script "./process1"
end tell'
osascript -e 'tell app "Terminal"
do script "./process2"
end tell'
Basically, it will open two different terminal windows (on mac) and execute defined commands. I try to do this in java by
process1 = Runtime.getRuntime().exec(new String[]{"process1"});
process2 = Runtime.getRuntime().exec(new String[]{"process2"});
The problem is it seems that there is only one terminal is opened (and not visible - it runs in background) and then two command process1 and process2 are executed. But because the process 1 will keep that terminal busy thus process2 cannot run. That's why I want to open different terminal to execute those commands.
Create a thread for each one of them. and give a time space "sleep(for some time thread 1 or 2)" and this will run both depending on you operating system.

How to set up a cron job to start and stop a java jar?

I have compiled my JAVA code into a jar file which I have ported to my ubuntu server. I can start it manually the usual way using java -jar myJar.jar but I'd like my program to be active only for 8 hours. How can I go about setting my jar file up as a process which starts at 9AM and also which automatically closes at 5PM?
I would write a simple launcher script that does the following:
Takes two command line options:
--start
Set up the classpath and environment like JAVA_HOME for the jar to run.
Spawn java -jar myJar.jar.
Capture the process ID and store it in the myJar.pid file in a specific location.
--stop
Read the process ID from myJar.pid and send a kill signal.
Then schedule two jobs in cron, one to call this launcher script with --start argument, at 9AM, and the other to call the same script with --stop argument, at 5PM.
I would also have a shutdown hook registered in my application to gracefully exit when the kill signal is issued.

Categories