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
...
Related
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)
I have a shell script on a remote linux machine which contains the following:
#!/bin/sh
for i in $(seq 1 10);
do
echo "CREATE TABLE ben$i (id NUMBER NOT NULL);
! sleep 30
select * from ben$i;
! sleep 30
DROP TABLE ben$i;" | sqlplus system/password &
done
wait
The name of this script is ben.sh.
In java, i want to execute this script and keep the script doing what it does in background.
I have a command that execute the script successfully:
sshshell.execute("su - oracle -c './ben.sh'");
I want the script to still run on the remote linux machine and i want to close the ssh connection right after i execute the command above, without interfering the script.
I thought if i put an & at the end of this command like so:
sshshell.execute("su - oracle -c './ben.sh' &");
But still the java program stuck and waits for the script to finish
Very important note: I don't want to use Threads OR any additional ssh connections.
What are my options here?
Use nohup and & to run the script in the background.
sshshell.execute("nohup su - oracle -c './ben.sh' &");
Nohup is short for “No Hangups". Nohup is a supplemental command that tells the Linux system not to stop another command once it has started. That means it’ll keep running until it’s done, even if the user that started it logs out. The syntax for nohup is as follows:
nohup sh your-script.sh &
The & at the end moves the command to the background, freeing up the terminal that you’re working in.
So, you canuse Nohup or Disown commands. With nohup system will avoid exit signals propagating to child processes.
nohup cmd &
Or you can use Disown to deatach it from child proceses.
cmd & disown
I want to make job on Jenkins that starts server (MockServer on WireMock).
Server is launched from *.jar file, from terminal like that.
java -jar serverLaunch.jar
It takes over my console. To avoid that I modify this and do:
java -jar serverLaunch.jar &>/dev/null &
And that works for me on my local PC. Now I want to move it to Jenkins.
If I try to do this from "Shell command" block in Jenkins Job then:
a) java -jar serverLaunch.jar
I have task locked in queue in my Jenkins and I don't want that but server starts and works.
b) java -jar serverLaunch.jar &>/dev/null &
Job ends with success but my server is not alive.
I have wrapped this command also in .sh script and .rb script. Any idea how to make it work?
I've tried this:
https://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build
And then in Jenkins "Shell script":
daemonize -E BUILD_ID=dontKillMe /bin/bash launch.sh
But it also passes but server is not alive.
I had to check "Inject environment variables to the build process" and add:
BUILD_ID=dontKillMe
Now it is working.
Try using nohup e.g.:
nohup java -jar serverLaunch.jar &
That should prevent the process being terminated when the parent shell process exits (which I suspect is your problem).
Another effective approach would be to add a post-build action that executes a shell spawning the server.
I am writing a cron job to my crontab file using following java code
PrintWriter writer = new PrintWriter("/var/spool/cron/crontabs/multi","UTF-8");
String cronTabString="25 13 * * * sudo wget --tries=0 \"https://some-url.com:7443/DataUpdater/updateChildren?folderId="+folderId+"&clientId="+clientId+"&clientSecret="+clientSecret+"&refreshToken="+refreshToken+"&deptName="+deptName+"\"";
writer.println(cronTabString);
writer.close();
The code is successfully writing to cron tab file . But it does not run . My question is that is it even possible to execute a cron job in this manner ? According to me it is a valid cron tab entry , so it should get executed . Am i missing something here ?
Try the following:
crontab -r
crontab /var/spool/cron/crontabs/multi
(edit) I believe in Java, you can call these this way:
Runtime.getRuntime().exec("crontab -r");
Runtime.getRuntime().exec("crontab /var/spool/cron/crontabs/multi");
First one removes the existing crontab. Second one installs the new crontab. And then you can verify by doing:
crontab -l
The crontab scheduler is not just a file. It is a process that runs as a daemon. When you traditionally edit the crontab file its saves the crontab entries and reload the crontab process. Because of this reason, simply writing to the file will not help. You will need to reload or restart the cron daemon.
Update
You can restart the cron daemon if you have root access on the server by using the following command:
/etc/init.d/cron reload
So, in your Java program running on the server, you will need to do this:
Runtime.getRuntime().exec("/etc/init.d/cron reload");
This will run the system command to restart the cron daemon and reload the cron entries.
Hope this helps!
Update 2
Different flavors of Linux have different commands to restart services or daemons.
You can use this as a good starting point to check which command will go as a parameter into the exec method above.
Cron Command Syntaxes on different Linux Versions
I have an Ant Task in the Jenkins Ant Execution Plugin, as a Post Build Step, to remotely run a shell script in one of our servers. The shell scripts starts a java process in the background. When I execute the shell script on the server directly it starts the java process in the back ground and comes out. When I run it from Jenkins via the sshexec task the shell script is run, but it never comes out and the Jenkins Build waits.
Later when I added the timeout attribute onto the sshexec it times out after the given number of milliseconds, but the Jenkins build is shown as failed. How do I make the sshexec task to come out cleanly from the shell script execution?
Here is my ssheexec task
<sshexec host="${deploy.host}" username="${deploy.username}" password="${deploy.password}" command=". /etc/profile; cd ${deploy.path}; sh start.sh i1" trust="true" timeout="10000" />
The start.sh file is as given:
nohup java -Xms512m -Xmx1024m -cp calculation.jar com.tes.StartCalculation $1 &
echo $! > calculation-$1-java.pid
It looks like, the ssh executed job is not fully daemonized. Starting with nohup is not sufficient in many cases.
See the discussion that related to it (in a different context)
The issue is that you are not closing your file descriptors when you
push something into the background. The & is fine when you are in a
shell, but is not enough when you want to disconnect and leave a
process running, you need the process to disconnect from the shell.
.... Fix to to correct the script.
If someone writes a naive service script that does not properly detach
from the terminal, I want to know the first time that that script is
used in a deployment - the SCM changes will enable the breaking change
to be quickly identified.
It is wrong to hide the problem to enable incorrect code to be
released to production - and I would not be happy if the first I knew
about it was when a production system administrator complained.
If this is the same problem, you need to daemonize the script