Shell script exits unexpectedly, when calling another shell script - java

I'm creating a java application that calls shell script.
ProcessBuilder pb = new Processuilder("./script.sh", path1, path2);
Process p = pb.start();
this starts the script.sh file.
PROBLEM occurs when script.sh calls another shell script which is # path2.
======script.sh=====
1.#some code
2.
3.
4.
5.
6. cd $2 # works till here, and changes directory
7. chmod +x script2.sh
8. ./script2.sh
.
.#remaining code
===========
the script exits # line7 without any error or warning.
Please guide.

Related

Shell scripts run one after another

I have 5 shell scripts. Each has a java command. Previous jobs output is input to the next job.
I created a superScript.sh
//mail - to inform beginning
sh script1.sh;
sh script2.sh;
sh script3.sh;
sh script4.sh;
sh script5.sh;
//mail to inform end
Sample script1.sh
cd toBaseDirectory;
java -cp /path/to/application.jar main.class parameter
But all the jobs are started at the same time. How can I make this sequential?
Try to run javas like this
java -cp /path/to/application.jar main.class parameter & wait
If want to run the second command only if the first exited successfully. To do so, join them with &&
command1 && command2
simple Example
~$ cat abc.sh
#!/usr/bin/env bash
echo "hi"
~$ cat pqr.sh
#!/usr/bin/env bash
echo "batman say : $1"
If abc.sh execute successfully then only execute pqr.sh
~$ retval=$(./abc.sh) && result=$(./pqr.sh "$retval") && echo "$result"
batman say : hi
you can also try similar approach with your java command execution using shell script
Note:
To execute Shell scripts as command sequentially, waiting for the first to finish before the next one starts. You can use ;
command1; command2
wait waits for a process to finish
You can also choose to run the second command only if the first exited successfully. To do so, join them with &&
cmd1 && cmd2
but In repetitive cases like this I recommended using a simple loop in the body of your script:
for n in {1..5} ; do sh script${n}.sh ; done
The loop not only to run them in order but is easier to tweak and reuse when needed, with using brace expansion

Unable to run nohup command from jenkins as a background process

UPDATE: Based on below discussion I have edited my answer for more accurate description.
I am trying to run a nohup command from jenkins. The full command is
nohup java -jar /home/.../jar/server-process-0.35.jar prod >> /var/../server-process-prod.log 2>&1 &
This command does not work. I can see status as success in jenkins but no java process in linux. When I do 'ps -ef | grep java'
However when I remove the last '&' , that is I change it from run in forground instead of background
It starts working. I can see the java process started.
The original command works fine If I run it on linux console.
I need to run it from jenkins in the original form that is as a backgorund process. So that it is independant of jenkins.
Any clues why is this happening?
Long story short, Jenkins kills all processes spawned by a job once that job finishes. To override this behavior, you need to set an environment variable.
The variable appears to vary from job type to job type. It used to be BUILD_ID, but for Pipeline jobs it is JENKINS_NODE_COOKIE, and there are several others mentioned in this answer.
So if you're running your command in Pipeline, it would look like this:
sh 'JENKINS_NODE_COOKIE=dontKillMe nohup java -jar /home/.../jar/server-process-0.35.jar prod >> /var/../server-process-prod.log 2>&1 &'
See the wiki on ProcessTreeKiller and this comment in the Jenkins Jira for more information.
In your jenkins shell script try:
export BUILD_ID=dontKillMe
nohup java -jar your_java_app.jar &
It worked for me!
I tried every possible combination with BUILD_ID but it didn't work.
I made it though by putting "nohup command > output.txt&" inside a shell script ran by the execute shell in jenkins, it worked perfectly!
Got the same problem, added:
BUILD_ID=dontKillMe python /var/lib/jenkins/release.py
into Execute Shell -> Command and inside release.py there is:
os.system('nohup java -jar ' + new_jars_on_server + '/' + generated_jar_by_mvn_name + '&')
and it works
Best simple solution is to use "at now" instead of "nohup"
In your job jenkins (execute shell) put :
set +e #so "at now" will run even if java -jar fails
#Run java app in background
echo "java -jar $(ls | grep *.jar | head -n 1)" | at now + 1 min
what worked for me was wrapping the nohup java -jar ... command into sh file inside execute shell command, and running that same sh file right after:
echo "starting java jar..."
cd [some location where jar is]
echo "nohup java -jar [jar_name].jar &" > start-jar-in-background.sh
sh start-jar-in-background.sh
echo "started java jar"
If I had nohup java -jar ... inline with Execute shell command, then it didn't start it from some reasons. I spent quite some time on this, hope it helps to someone ';)
Simplest way :
`nohup java -jar [jar_name].jar >log_file_you_want 2>another_file`&
set +e #so "at now" will run even if java -jar fails
#Run java app in background
echo "java -jar $(ls | grep *.jar | head -n 1)" | at now + 1 min
above command worked for him, thanks #walid, & remove at the end (+ 1 min)

Error executing ant :-bash: ant: command not found

I am trying to deploy my application in a Linux box, I have a file called setAppPath.sh file as:
#!/bin/sh
APP_HOME=`pwd`
ANT_HOME=$APP_HOME/lib/ant
echo $ANT_HOME
PATH=$ANT_HOME/bin:$APP_HOME/scripts/unix:$PATH
echo $PATH
chmod +x $ANT_HOME/bin/ant
chmod +x $APP_HOME/scripts/unix/*.sh
export APP_HOME ANT_HOME PATH
When I try to execute ant command I get an error message as:
-bash: ant: command not found
The echo $ANT_HOME is printing my ant home location the PATH is printed properly too.
After execting setAppPath.sh file I tried echo $ANT_HOME it gave empty line.
Please help me figuring out this issue.
Edit 1: which ant give no ant
I am using sh setAppPath.sh command to execute the sh file.
When you run your script normally, what happens is that your shell starts a new process, the script runs in that process, and when the script is done the process dies and control returns to your shell.
All modifications that the script did to its environment die with it. The changes have no effect on the parent shell. Same if you're trying to run cd in a script and expecting the parent shell to move.
To run your script in the context of your shell and not in a subprocess, use the source or . commands:
source setAppPath.sh
. setAppPath.sh

Running Scrapy from bash (shell script)

I have developed a web app in Java which uses Scrapy to get some data. To reach that, I invoke a shell script from Java:
Process p = Runtime.getRuntime().exec("sh myPath/myScript.sh");
p.waitFor();
which contains
#!/bin/bash
cd mySpiderPath
echo "We are going tu run scrapy"
scrapy crawl mySpider
echo "done!"
After running it, both "echo" are printed but scrapy does nothing. If I run myScript.sh from shell it works perfectly... I'm confused!
What can I do to try to debug this strange behavior?
EDIT
I have changed myScript.sh to run python version instead of scrapy command, and it doesn't work... so, the conclusion is that is not an "scrapy problem" but it is a bash script problem when it's invoked from Java...any ideas? (if I execute myScript.sh from shell it works fine)
#!/bin/bash
cd mySpiderPath
echo "We are going tu run scrapy"
python --version
echo "done!"
Try changing:
Process p = Runtime.getRuntime().exec("sh myPath/myScript.sh");
to:
Process p = Runtime.getRuntime().exec("bash myPath/myScript.sh");
This will probably run the script with /bin/bash instead of /bin/sh, that often points to a simpler shell.

Not able to run grep command

I was trying to run the following instruction,
Process p = Runtime.getRuntime().exec("/system/bin/lsof|grep mediaserver");
In android(java) but I am getting error. if I run following instruction,
Process p = Runtime.getRuntime().exec("/system/bin/lsof ");
the file is successfully saved.Can anyone tell what is the error? Actually I want to list and check if media server service is being running or not.
The grep utility may not be installed on your device.
You can check it by trying the following in a console:
> adb shell
$ grep
grep: not found
The last line indicates that this command is not available.
The problem is that Runtime.getRuntime().exec(...) does not know how to deal with the shell language. On a Linux / Unix platform you would so something like this:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/sh", "-c", "/system/bin/lsof | grep mediaserver"});
However, (apparently) Android doesn't have a command shell / command prompt by default. So either you need to identify and install a suitable shell on your device, or construct the pipeline "by hand"; i.e. by creating a "pipe" file descriptor, and execing the two commands so that lsof writes to the pipe and grep reads from it.
Maybe the answer is to run it like this ...
Process p = Runtime.getRuntime().exec(
"adb shell /system/bin/lsof | grep mediaserver");
(Try running the "shell ...." part from adb interactively before doing it from Java.)

Categories