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.
-
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
-
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.
Michael Myers : "Prejucide"? Is that a joke or a typo?Don Werve : That's what happens when I post an answer before the morning coffee.Don Werve : Also, if you've got the 'seq' command, you can do 'seq 1 10' instead of the manual count. Isn't always available on every flavor of Linux, though. -
ps aux | grep java | awk '{print $1}' | xargs kill -9
Here's an explanation:
ps aux
gives you a listing of all processesgrep 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 columnxargs kill -9
passes each of the results of the awk command as parameters to a kill -9 commandandri : Skip the grep: ps aux | awk '/java/ { print $1 }' :)Eli Courtwright : Thanks for the tip; I don't know awk well enough to have known how to do that. I'll leave my answer as it is because it's simpler for me personally to understand, but I'm glad you made that suggestion.Chas. Owens : Shouldn't you have a grep -v grep in there to stop it from collecting grep's pid (since its commandline contains the word java)?Eli Courtwright : Technically yes; I left that out for two reasons. First, when the kill command runs, that process id will be defunct, so it doesn't hurt to leave it in (though you will get a warning message). Second, it makes the call chain less complex for a newbie to understand. You have a good point though. -
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)
orpkill(1)
if your system has them. No more pipes, seds, awks, cuts, xargs:pkill -9 java
Jay : I almost posted the same thing, but ps -e doesn't list cmd arguments (at least on my box) so there's no danger of accidentally capturing the 'grep java' command itself in the grep output.Martin Carpenter : Spot on, Jay, at least for Linux. I still prefer pkill but it looks like I'm in a minority.dannysauer : You can also stick brackets around the first char in the grep, as in grep [j]ava The grep sees that as a regex and looks for a j, but the command line will not match the pattern. :) It makes me feel dirty when I do it, but it works well... -
I use something like this:
kill $(ps -A | grep java | cut -b 1-5)
0 comments:
Post a Comment