I have an Ubuntu VM dedicated as a Jenkins slave. I wrote a one-liner script to run the slave jar, and I run that script from /etc/rc.local. When I run the script manually, I get a few lines of output showing that it's working. I've tried to define the rc.local line and the script so that it stores stdout/stderr in a file, but the file is always zero length, with a modtime of when I start the process.
In the following, some fields are elided with "=stuff=".
The end of my "/etc/rc.local" looks like this:
su -c "/home/=user=/bin/jenkinsconnect" =user=
exit 0
The "jenkinsconnect" script looks like this:
#! /bin/bash
java -jar /home/=user=/opnfv_slave_root/slave.jar -jnlpUrl https://=host=/ci/computer/att-build/slave-agent.jnlp -secret =secret= 2>&1 > /home/=user=/jc.log
As I said, "/home/=user=/jc.log" is always zero length, and the modtime is when I started the process.
The 2>&1 > file syntax will not work. You should either:
use &> for directing both stderr and stdout to a file, or
surround the entire command with parentheses to capture the output:
(java -jar /home/=user=/opnfv_slave_root/slave.jar ... 2>&1) > /home/=user=/jc.log
Related
I want to execute a jar file of DOMO CLI from a shell script. The jar file itself has some functions which I want to call after I call the main jar file. The problem which I am facing is that after it executes the jar file, I am not able to pass the additional commands to execute inside that jar through a shell script. It just stops after calling jar and doesn't take further commands. Can anyone please help? Below is the code I am calling from a shell script.
java -jar XX.jar
The commands are as below which follow the above jar. So once we enter into the above jar we have to execute the below commands one after the other. I am not sure how to achieve this through a shell script.
connect -s X.domo.com -t Ysssss
upload-dataset -a -i dhdhdhdh -f /prehdfs/dev/comres/herm/data/yyyy.csv
Did you try using pipes and inputs.
When you execute above it runs it under a child shell.
You may try below format if not tried already
$ (echo "connect -s X.domo.com -t Ysssss" && cat) | java -jar XX.jar
If you can reference a file in your use case, you could put your commands in a file.
File: list_my_datasets.domo
connect -t ... -s ...
list-dataset
quit
then run the command:
java -jar domoUtil.jar -script list_my_datasets.domo > datasets
I wanted the data from it so I piped to a file (where I had to grep what I wanted), but you would omit that I believe, unless it has some output you'd want to check. I haven't tested with the upload command, but I would hope any commands substituted or added to the example work similarly.
Domo docs on scripting
I created a docker image from openjdk:8-jdk-alpine using the below Dockerfile:
But when I try to execute simple commands I get the following errors:
/bin/sh: ./run.sh: not found
my run.sh looks like this
enter image description here
I try to "docker run -it [images] bash" enter to the interactive environment,I can see the file "run.sh".In the directory /bin bash exist,but I execute run.sh also display " /bin/sh: ./run.sh: not found"
PS:Sorry for my poor english,I am a chinese student
The printed content of the run.sh, indicates that my original assessment was incorrect; however based on the error message, and the image of the run.sh file, I have a lead.
Your run.sh script has an exec line of #!/bin/sh, which means that it does not need bash to operate so my previous assessment was incorrect.
Starting on a mac, I created a run.sh script, duplicated the dockerfile (mostly), and it ran correctly, producing a valid run.
I then converted the run.sh to use dos line endings and got the following:
$ file run.sh
run.sh: POSIX shell script text executable, ASCII text, with CRLF line terminators
$ docker run --rm -it bob
/bin/sh: ./run.sh: not found
Which looks suspiciously like your error message.
From this, it would lead me to believe that your run.sh file contains dos line endings. Based on the images, I'm guessing that you're on windows, which is where the problem with the run.sh script originates.
how to convert the line endings (some examples):
dos2unix run.sh
perl -pi -e 's/\r\n/\n/g' run.sh
Previous Answer
The most likely reason for this issue is that the shebang line in the run.sh contains: #!/usr/bin/bash, or something of that ilk - i.e. it doesn't reference the valid path to the binary that will run the shell script.
On alpine, bash is installed into /bin, so if you try to run the script you will see the error:
/ # ./run.sh
/bin/sh: ./run.sh: not found
/ # cat run.sh
#!/usr/bin/bash
echo "Hi"
workaround (1): after the apk add bash, do an:
RUN ln -s /bin/bash /usr/bin
in your Dockerfile. This will create a symlink for bash, allowing the program to run:
/ # ln -s /bin/bash /usr/bin
/ # ./run.sh
Hi
workaround(2) - if you don't want to make a symlink like this, you can always invoke bash as part of the CMD -
CMD [ 'bash', './run.sh' ]
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)
I have used the following scripting for start and stop a jar file.
**start.sh**
#!/bin/bash
nohup nice java -jar Server.jar > ./Server.out 2>&1 &
**stop.sh**
#!/bin/bash
kill `ps -ef | grep Server.jar | grep -v grep | awk '{ print $2 }'`
Now I want to merge both scripts and create a new restart script. I also want this script output in a terminal instead of a text file(Server.out).
Would appreciate any kind of input/help.
You can either put the commands of the two sripts after each other (kill first, java second) or just call the two scipts in the appropriate order.
The idea is that restart is basically equivalent to killing the current running version and starting a new one.
To avoid the output to a file, remove the > ./Server.out part.
Edit: removed note about removing the redirection part as I misread the grep part of the kill script
Update: Missed the nohup part of the script: with nohup you need to redirect output to a file, because the process is detached from the terminal (see documentation). If you do want to see the output in the terminal, remove nohup as well as the redirection to the file
I have a program in java which takes 0'th aargument as file location like
File f = new File(args[0]);
so when i execute it using a windows batch(.bat) file it works correctly .
but when i execute the same using a linux shell file(.sh) in linux i get ArrayIndexOutOfBoundsException.
WINDOWS BATCH FILE :
#echo off
for /f %%i in ("%0") do set scriptpath=%%~dpi
set cp=%scriptpath%/../lib/*.jar;
java -classpath %cp% com.synchronizer.main.MYSynchronizer %scriptpath% "%1" "%2"
LINUX SH FILE:
export JAVA_HOME=/usr/local/java
PATH=/usr/local/java/bin:${PATH}
THE_CLASSPATH=
for i in `ls ../lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
java -cp ".:${THE_CLASSPATH}" \
com.synchronizer.main.MYSynchronizer
please help!
It looks like a problem in script (no arguments are passed to the Java program).
You can consider to debug the script like this: debugging scripts
Hope this helps
Your shell script is not passing any parameters:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer
Try:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer "$1" "$2"
As stated above, your Linux shell script is not sending any arguments to the Java program that you are trying to start.
And, adding to that, you are not showing us how you run the Linux shell script. If no argument is given on the command line when you start the shell script, no arguments can be passed to your Java application from the shell script.
If you want to see the actual command that is going to be run by your shell script, you can always put "echo" in front of a line and see what all variables are expanded to. This is a simple way to debug shell scripts.