Shell script to stop a java program - java

Is there a way to stop a java program running using a shell script by knowing the name alone.I am using ksh shell

following up on Mnementh' suggestion:
this should do the job
jps -l | grep org.example.MyMain | cut -d ' ' -f 1 | xargs -rn1 kill
jps -l: list java process with "full package name for the application's main class or the full path name to the application's JAR file."
grep: choose the process you like
cut -d -' ' -f 1: split the output in columns using delimiter ' ' and print only the first one (the pid)
xargs -rn1 kill: execute kill for each PID (if any)
note that you must run jps and xargs with the same user (or root) as you're running the process

Add a unique property to the JVM to identify it easily, e.g. for test.class
java -Duniquename=1 test
To kill it:
ps ax | grep uniquename | grep -v grep | awk '{print $1}' | xargs kill

You can use jps identifying the process-id associated with the name of the started java-program (jps is a process-manager for java-programs). With this id you can kill the process normally.

You can use pkill:
pkill your_java_program_name
This would work if you run only one instance of the your program is running.

you can use -o option of ps to format your output,
ps -eo cmd,pid | awk '!/awk/&&/mycommand/{cmd="kill -9 "$2;system(cmd)}'

Related

kill a java process in Linux

I have a BI application (looker) runs on a linux VM.
tobe able to restart the service, I need to clear the existing java process.
In below screenshot, after run below script, there is a java process, but not showing in the list when I run jps script. What's the reason? and how can I properly terminate this java process?
ps aux | grep java
Have you tried these ?
killall java
or
kill $(pidof java)
As you can see from your image, the process id is changing each time 9287 / 9304 and represents | grep java - and not a java VM!
A common fix is to filter the ps results for not matching | grep -v, such as:
ps aux | grep java | grep -v --regexp=grep.\*java
If there are results above you could append commands to read the process ids and kill command:
kill -TERM $(ps aux | grep java | grep -v --regexp=grep.\*java | awk '{print $2}')
Note: the above will kill all processes with "java" in name so is not very useful if there are multiple java services for same account. You may need to add filter for specific Java VMs.

Runtime.getRuntime().exec(command) - Cannot run program, error=2, No such file or directory

I want to get video duration with help of ffmpeg:
String command = "ffmpeg -i /home/user/Videos/my-video.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,"
Runtime.getRuntime().exec(cmdarray);
But i always get
java.io.IOException: Cannot run program "ffmpeg -i /home/user/Videos/my-video.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,": error=2, No such file or directory
If I run this command from terminal - all is ok
You've got several issues here. Firstly as #joy points out there could be a problem with the Path used by Java to locate the command so Java may not be finding a command called "ffmpeg". Fixing the Path used for launching your VM should resolve that, or just insert the fully qualified pathname to "ffmpeg".
Secondly: you are trying to run a terminal / shell command. The "|" pipes are normally interpretted correctly by a terminal / shell which breaks the chain into sub-processes linking stdout/stdin. But Java is being asked to run "ffmpeg" passing in some arguments containing "|" which would not be handled as you wish by "ffmpeg".
Check the shell you use:
echo $SHELL
Let's say that printed /bin/bash - you can fix by getting Java to launch the shell and make that interpret the pipe command:
String[] command = new String[] { "/bin/bash", "-c", "ffmpeg -i /home/user/Videos/my-video.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ," };
Runtime.getRuntime().exec(cmdarray);
Most likely the path isn't the same when you run from terminal vs when you run from Java. 1. you can try using the full path of ffmpeg (run "which ffmpeg" in terminal). 2. perhaps ffmpeg is an alias in your .profile file in that case you can try to source(load) your .profile file first before executing the command in Java.

How to stop the process from running?

This question might be a bit similar to this or this question.
How do I stop a particular .jar file from running in Mac OS? When I open up the activity monitor, it does not show the process listed. But I am sure it is running because when I visit the localhost (I have developed a .jar from a Spring Boot application), I can still see the welcome message!
Could you please let me know how I could stop a particular .jar file from executing? Thanks.
You can use jps to get the pid (and jar name), awk to parse the pid and then kill it. Like, (with bash or similar)
kill -9 $(jps | grep -i "thejar.jar" | awk '{print $1}')
or
kill -9 `jps | grep -i "thejar.jar" | awk '{print $1}'`
The -i option to grep makes it case insensitive. Omit if that is not needed.
Step1: ps -aux | grep xxx, xxx is the name of .jar
Step2: kill -9 pid, pid you can get from the first command.

Shell script. How to kill java process and then start it again with nohup

I'm trying to do it like this:
file_name=$1
#Clear log file
echo > nohup.out
for PID in $(ps aux | grep service_name | awk {'print $2'}); do
kill -9 $PID;
done
echo "Killed old process"
nohup java -Xms256m -Xmx256m -XX:MaxMetaspaceSize=256m -jar $file_name &
echo "Started new process"
But it's just printing "Killed" and doesn't start it again.
If I do all this stuff separately - it's working, but for all together - not...
Допоможіть хто зможе...
The script from which you execute it, does it contain "service_name" in its name? Then it obviously fulfills the criteria for begin killed by your for loop and commits suicide.
If it does not, then still the grep service_name remains which fulfills the kill criteria (has service_name in its cmd line) - for fixed strings in grep I usually write them grep "s[e]rvice_name", other prefer to put another |grep -v grep into the pipe before the awk

How to capture the result of a system call in a shell variable?

We want to build a script that run every night (kills and restart a java process). For that we need to capture the process number (since there could be more than one java process running). The command below is basically what we will use to obtain the processes number, probably with a regexp at the end of the grep. Unless any better suggestions comes up.
root#ps -e |grep 'java'
18179 pts/0 00:00:43 java
We want to know how to parse the output above and get it into a shell variable so we can use the kill command as below.
kill -9 ${processid}
wait 10
Note1: The reason we cannot rely on the normal service stop command is because the processes sometimes does not want to die. And we have to use the kill command manually.
There are a couple of options to solve this. If you're using bash, then the shell variable '$!' will contain the PID of the last forked-off child process. So, after you start your Java program, do something like:
echo $! > /var/run/my-process.pid
Then, after your init script stops the Java process:
# Get the pidfile.
pid=$(cat /var/run/my-process.pid)
# Wait ten seconds to stop our process.
for count in $(1 2 3 4 5 6 7 8 9 10); do
sleep 1
cat "/proc/$pid/cmdline" 2>/dev/null | grep -q java
test $? -ne 0 && pid="" && break
done
# If we haven't stopped, kill the process.
if [ ! -z "$pid" ]; then
echo "Not stopping; terminating with extreme prejudice."
kill -9 $pid
fi
Make sure to remove the pidfile when you're done.
ps aux | grep java | awk '{print $1}' | xargs kill -9
Here's an explanation:
ps aux gives you a listing of all processes
grep java gives you all of the processes whose names and command line arguments contain the string "java"
awk '{print $1}' parses the output of the grep command into columns by whitespace and re-prints only the first column
xargs kill -9 passes each of the results of the awk command as parameters to a kill -9 command
I realize this is old, but what about:
pidof java | xargs kill
You can easily get the PID or list of PIDs into a variable using backticks and cut (or awk if preferred) to retrieve only the PID field:
[user#host ~]$ ps -e | grep java | cut -d' ' -f1
12812
12870
13008
13042
13060
Note in the above example I have multiple Java processes running hence the multiple values. If you save this into a variable like so:
JAVA_PROCS=`ps -e | grep java | cut -d' ' -f1`
You can iterate through the processes to kill them if desired:
for proc in $JAVA_PROCS; do
kill -9 $proc;
done
Of course, if you're only retrieving one process, then there's no need to iterate and you can just run it as:
kill -9 $JAVA_PROCS
If you do what you suggest, you may end up capturing the grep itself and killing that (since your grep command contains the java string that you are searching for). You can work around this by excluding grep (by using another grep!):
pid=`ps -e | fgrep java | fgrep -v grep | awk '{print $1}'`
# check pid has a value
# kill $pid
You might also like ps -e -opid,args.
A better alternative is to use pgrep(1) or pkill(1) if your system has them. No more pipes, seds, awks, cuts, xargs:
pkill -9 java
I use something like this:
kill $(ps -A | grep java | cut -b 1-5)
killing it:
ps -e | grep java | cut -f1 -d' ' | xargs kill -9
storing PID on variable:
export JAVAPID=`ps -e | grep 'java' | cut -f1 -d' '`
checking that it worked:
echo $JAVAPID

Categories

Resources