I want my micro services to open in a new command line and run it from there one after the other. below is my bash script
################ first SERVER #####################
gnome-terminal -x sh -c 'java -jar server/target/first-server.jar; exec bash'
################ second SERVER #####################
export service_port=8771
export host_name=firstdomain
gnome-terminal -x sh -c 'java -Dservice.port="${service_port}" -Dhost.name="${host_name}" -jar eureka/target/second-server.jar; exec bash'
The problem is it that i want to start my "second-server.jar" after successfully started the "first-server.jar". I can detect that by checking if the service is listening to network port. Is there any way to archive this? sleep bash command is not a option for me.
Basically, you need to use sleep command. But you can use it in a loop checking continuously if the port became available. But how to check availability of the port?
One option is to use netstat command as suggested by Jack. The proper usage is:
netstat -tna | grep 'LISTEN\>' | grep ':NNNN\>'
where NNNN is the port. To make that a condition to wait on, you can write following loop:
while ! netstat -tna | grep 'LISTEN\>' | grep -q ':NNNN\>'; do
sleep 10 # time in seconds, tune it as needed
done
Please mind the -q option in the last instance of grep.
The other option is to check, if you can connect to port:
{
while ! echo -n > /dev/tcp/localhost/NNNN; do
sleep 10
done
} 2>/dev/null
Depending on the distribution you are using and the options bash has been compiled with, this method may or may not working.
Another option to check if port is accessible is to use nc:
while ! nc -q0 localhost 2222 < /dev/null > /dev/null 2>&1; do
sleep 10
done
You can replace localhost with your hostname or ip address.
Related
I am working on a Gradle Java project. Which starts Tomcat for testing and stops it later.
I am supposed to kill this Tomcat instance when the test fails.
I tried using "ps aux| grep tomcat | grep -v grap | awk {print $2}" command to get the process id and kill the process.
But on Production, there will be so many Tomcat processes running simultaneously by many users, I just want the tomcat process started by my build.gradle for test execution.
So how can I accomplish the task? Please provide me some guidelines.
You need to find a unique string in the output of 'ps aux' which differentiates your test tomcat and others'.
I currently use the below script to run 'shutdown.sh' first and then kill the PID as most of the times, the application stops but the process does not stop.
PID=`ps -ef | grep $JAVA_HOME/bin/java | grep "$TOMCAT_LOC"/conf | grep -v grep | awk '{ print $2 }'`
if [ $PID ]; then
echo tomcat is running with PID:$PID.
# Stop or Kill running Tomcat
if [[ -f $TOMCAT_LOC/bin/shutdown.sh ]]; then
[[ ! -x $TOMCAT_LOC/bin/shutdown.sh ]] && chmod a+x $TOMCAT_LOC/bin/shutdown.sh
$TOMCAT_LOC/bin/shutdown.sh >>/dev/null
sleep 20
fi
kill -9 $PID
sleep 3
else
echo tomcat is not running
fi
You may also look at configuring a PID file by editing the 'catalina.sh' which you can read later to find out your PID.
# CATALINA_PID (Optional) Path of the file which should contains the pid
# of the catalina startup java process, when start (fork) is
# used
Java JRE has tool called jps in $JAVA_HOME/bin folder.
It's similar to unix ps command but for java only.
You can use it to determined exac java process you need.
Using this tool is more recommended and actually it is more useful, when you have more than one java applications is running on your host...
for example I have running h2 database and many other apps, but wanna kill only h2, so I can use jps to get it PID
$ jps
17810 GradleDaemon
17798 GradleWrapperMain
17816 h2-1.4.197.jar
17817 GradleDaemon
17818 GradleDaemon
18011 Jps
16479
and then just kill needed process:
kill -9 17816
and all other java apps will continue work normally. I not sure about tomcat, but I think it can be done in similar way, something like that:
kill -9 $(jps | grep tomcat | awk '{print $1}')
Lastly, little bit offtopic, but a specially to your case: correct way would be using start/stop/restart scripts provided by tomcat
The correct way to terminate a Tomcat instance is via its own shutdown command. You should not be thinking of processes, or PIDs, or kills, at all.
so if you want to kill tomcat from that user from which you have logged in then try following and let me know if this helps you.
ps -ef | grep -v grep | grep `whoami` | grep tomcat
So by ps -ef I am listing all the processes then grep -v grep will remove the grep command's process then grep whoami will look for your currently logged in user then grep tomcat will look only for tomcat process, test it once and if All is Well then you could kill it.
By the way how about tomcat stop script? In case it is there you could use that also.
You can use shell variable $!. It represents the PID of the most recent background command.
yourCommand &
CMD_PID=$!
echo $CMD_PID
Basically I am automation an application and prerequisite of my automation is that I am using several 3rd party libs which starts certain processes. At the end of the code execution, I want to close all such processes. The only thing I know is that these process runs on specific port always (for example 61120).
As part of clean up, I want to close the process running on port 61120 programatically in Java.
You could use netstat -a -b to get the executables and the port numbers. After that you can taskkill the executables by name. But i never would use this on a productive machine because it's some kind of ...ahm... dangerous.
Better to start processes by java (Runtime.getRuntime().execute(...)) and end them if you do not need them anymore.
Through this you can get the desired processes and port numbers
netstat -a -b
Then there is a little API providing the desired functionality to operate with the processes:
https://java.net/projects/winp
Windows Process Library
try
netstat -a -o -n
Search for the port you need.
If the console output is more then re-direct it to some file like:
netstat -a -o -n > {drive}:/netlog.log
search port in that log file.
taskkill /F /PID
I have game server and I want to launch it on Asustor NAS Server. I have PuTTy and I write
nohup java -jar server.jar &
Good, it launch in background, but now I want to close it. How to do it? And how to know if app is running or not?
Normally when starting you get the pid returend like so:
~ $ nohup java -jar server.jar &
[1] 3305
~ $ nohup: ignoring input and appending output to ‘nohup.out’
to see if it is running you can issue
~ $ ps -ef | grep server
user1 3305 2936 0 13:58 pts/1 00:00:00 java -jar server.jar
if you see a line like the above it is running. You may also hava a look at the nohup.out file, which is written to the directory you started the server in, by using
tail nohup.out
to kill the process issue kill . Where pid is the process id, you either remembered, or will find out by looking at the second row of the "ps -ef | grep server" command, in our case 3305
kill 3305
kill without options tries to end the process gracefully. Read more abut kill and ps by using
man kill
and
man ps
respectively.
Try like this.
Get number of your job using:
jobs
then use fg command:
fg %job_num
When it will be on foreground you can press CTRL+C to kill the process.
I have a java jar program that I am trying to run on startup of my machine. Ideally, the shells script will check every 60 seconds to assure that the jar is running. How do I check if the jar is running on centos, this does not appear to be working?
My current .sh file:
#!/bin/bash
while [ true ]
do
cnt=`ps -eaflc --sort stime | grep /home/Portal.jar |grep -v grep | wc -l`
if(test $cnt -eq 3);
then
echo "Service already running..."
else
echo "Starting Service"
java -jar /home/Portal.jar >> /dev/null &
fi
sleep 1m
done
I used this for referencing so far.
Depending on what your program does, there may be more or less intelligent ways to check it. For example, if you have some server, it will listen on a port.
Then something like
netstat -an | fgrep tcp | fgrep LISTEN | fgrep :87654 # or whatever your port is
could do the job.
Then there is lsof, which could also detect listening ports.
Finally, you could connect and issue a pseudo request. For example, for a http server, you could use lynx or curl. For a server with a non-stamdard protocol, you can write a small client program whose sole purpose is to connect to the server just to see if it is there.
Store your process id in file and check for this process.
#!/bin/bash
while [ true ]
do
pid=$(cat /tmp/portal.pid)
if [[ -n "$pid" && $(ps -p $pid | wc -l) -eq 2 ]]
then
echo "Service already running..."
else
echo "Starting Service"
java -jar /home/Portal.jar >> /dev/null &
echo $! > /tmp/portal.pid
fi
sleep 1m
done
/tmp will be cleared on restart, all right in this case.
I did the very same scenario a couple of months ago. My task was to ensure a jar distributed java program to run 24/7 on a Linux server.
My program was console-based, started, did something then stopped.
I did a shell script that started, waited to end and then re-started the app in an infinite loop.
I installed runit, created a service and supplied this script as the run script. Works very well.
In general, the shell script ensures that the java program is running and runit ensures that the start script (which is our script) is running.
You find valuable info here: http://smarden.org/runit/faq.html
Rather than putting the process to sleep , I'd rather have it exit and use crontab to run the process every 1 min;which will check if its running or else just stop the script.
#!/bin/sh
declare -a devId=( "/Path/To/TestJar.jar Test1" "/Path/To/TestJar.jar Test2" ) #jarfile with pathname and Test as argument
# get length of an array
arraylength=${#devId[#]}
# use for loop to read all values and indexes
for (( i=1; i<${arraylength}+1; i++ ));
do
y=${devId[$i-1]}
cnt=`ps -eaflc --sort stime | grep "$y" |grep -v grep | wc -l`
if [ $cnt = 0 ]
then
java -jar $y& > /dev/null
b=$(basename $y)
echo $b
#DO SOME OPERATION LIKE SEND AN EMAIL OR ADD TO LOG FILE
continue
elif [ $cnt != 0 ]
then
echo 'do nothing'
fi
done
Why do you think $cnt should be equal to 3? Shouldn't it be equal to 1 if the process is already running?
You could use the jps command. It return the JVMs running in the system.
I created following script to monitor my application jar is running or not.
In this case My application jar is running on port 8080
#!/bin/bash
check=$(netstat -an | grep 8080 | wc -l)
if [[ $check -eq 0 ]];then
echo "jar is not running..."
/usr/bin/java -jar /path/to/target/application.jar >> /dev/null &
else
echo "it is running"
fi
I am using cronjob to monitor jar app by executing shell script on every minute.
$ crontab -e
in the end of file
* * * * * /bin/bash monitor-jar.sh /dev/null 2>&1
I am developing an application where i required to run some of the scripts of unix from Java Code.
Platform i am using is Unix, Tomcat 5.5..
For that, My Sample Code is as follows :
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("netstat -i|tail -n +3|cut -d ' ' -f1");
System.out.println("exitValue = "+proc.exitValue());
I have given all the rights to tomcat user.
Now, my program output cases are :
Script exitValue()
======= ============
netstat -i 0
netstat -i|tail -n +3 4
sudo netstat -i 1
sudo netstat -i|tail -n +3 1
Above table suggest that only 1st script is executing in unix, all others are failing.
I am not sure, but i am just assuming that i have to run Tomcat Server as a root user..
Can anybody have any other solution, then please reply..
Thanks in advance...
If I remember correctly, pipes ("|") are handled by the shell. Java will probably not handle them at all ...
There are a few workarounds :
run bash with your commands as a parameter :
runtime.exec("bash -c \"netstat -i|tail -n +3|cut -d ' ' -f1\"");
write a bash script that run all those commands and run this script from Java :
#!/bin/bash
netstat -i|tail -n +3|cut -d ' ' -f1
create the pipes in Java : read the output of netstat -i and connect it in Java to tail -n +3 ...
Using | to chain commands in Unix is part of the shell, and Runtime.exec() runs the command directly, not though the shell. A quick fix may be (untested as I don't have a Unix box available at this moment) to prefix the shell as the first command.
Process proc = runtime.exec("/bin/sh netstat -i|tail -n +3|cut -d ' ' -f1");
Got the solution of above problem..
I have just created simple shell script file, and put the script inside that .sh file.
Now at the java side, i am just calling simple shell script file..
Process proc = runtime.exec("sh /usr/tmp/try1.sh");
That's it!!!