26

I have a Java program running on a Linux computer, and want to find the process ID (pid) of its process. I know the ps command can provide this information, but its output is confusing because it has so much extraneous information. How can I get just the pid?


I am using MPJ library in java program for Pagerank algorithm. I compile it by

javac -cp .:$MPJ_HOME/lib/mpj.jar MpiPageRank.java

and run by

mpjrun.sh -np 2 MpiPageRank

where -np is number of process

Now i have to find its pid

ps -ef|grep java

like

mpjrun.sh -np 2 MpiPageRank & sleep 2
ps -ef | grep java

I get

pnewaska 27866 27837 99 21:28 pts/45   00:00:09 java -cp /u/pnewaska/mpj-v0_38/lib/smpdev.jar:/u/pnewaska/mpj-v0_38/lib/xdev.jar:/u/pnewaska/mpj-v0_38/lib/mpjbuf.jar:/u/pnewaska/mpj-v0_38/lib/loader2.jar:/u/pnewaska/mpj-v0_38/lib/starter.jar:/u/pnewaska/mpj-v0_38/lib/mpiExp.jar runtime.starter.MulticoreStarter /nfs/nfs1/home/pnewaska/DistributedSystems/Project3 10 smpdev useLocalLoader EMPTY MpiPageRank -i input.500k0 -n 10 -o

Now I want to extract MpiPageRank from only 1 linux comman to get its pid ie 27866. how do i do that ?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Shweta B. Patil
  • 1,131
  • 2
  • 11
  • 19

5 Answers5

32

using ps

ps allows the user to define his own formatting for its output with the -o switch, and -C to select entries by the given command. I would go with:

ps -C java -o pid

from the man page:

   -C cmdlist      Select by command name
                   This selects the processes whose executable name is given in cmdlist.

   -o format       user-defined format.
                   format is a single argument in the form of a blank-separated or comma-separated list, which offers a way to specify
                   individual output columns. The recognized keywords are described in the STANDARD FORMAT SPECIFIERS section below. Headers
                   may be renamed (ps -o pid,ruser=RealUser -o comm=Command) as desired. If all column headers are empty
                   (ps -o pid= -o comm=) then the header line will not be output. Column width will increase as needed for wide headers; this
                   may be used to widen up columns such as WCHAN (ps -o pid,wchan=WIDE-WCHAN-COLUMN -o comm). Explicit width control
                   (ps opid,wchan:42,cmd) is offered too. The behavior of ps -o pid=X,comm=Y varies with personality; output may be one
                   column named "X,comm=Y" or two columns named "X" and "Y". Use multiple -o options when in doubt. Use the PS_FORMAT
                   environment variable to specify a default as desired; DefSysV and DefBSD are macros that may be used to choose the default
                   UNIX or BSD columns.

One can get more accurate results by specifying more restrictions (ie the user under which the process runs, etc). Look at the man page for more information and other switches.

example:

$ sleep 10 &
[1] 12654
$ ps -C sleep -o pid
12654

using the shell

I don't know why you use an .sh script to run your code and not call java directly, but if in any case you use the & (background) operator, you can grab the pid through your shell, with the $! variable.

for example:

$ sleep 5 &
[1] 12395
$ echo $!
12395

same goes for the java -jar .. & command, $! will be set to the pid of the last backgrounded job.

c00kiemon5ter
  • 16,994
  • 7
  • 46
  • 48
  • How to get the pid of this: `nohup java -jar application/target/application-0.9.0.jar &`? PS returns something like `14943 ttys003 0:43.93 /usr/bin/java -jar application/target/application-0.9.0.jar`. For `-C` I get an "illegal argument" error if I add anything about java or jar. – Wlad Nov 18 '19 at 12:56
  • SOLVED: answer to my question in comment above: `jps | grep application-0.9.0.jar | awk '{print $1}'` – Wlad Nov 18 '19 at 13:00
19

You can use awk to get the pid:

ps -ef | grep MpiPageRank | awk '{print $2}'

I noticed that sometimes grep itself gets found, to remove it:

ps -ef | grep MpiPageRank | grep -v grep | awk '{print $2}'
Abdullah Jibaly
  • 53,220
  • 42
  • 124
  • 197
  • that's not the correct way to use `ps`. Please look at my answer for some goodies `ps` offers. There is no need to `grep` the command. – c00kiemon5ter Apr 18 '12 at 02:14
  • 3
    -C only checks for the "java", what if you have more than one java program running and you need to check the PID of a particular java program. The grep is better than the -C ps thingy. – Siddharth Apr 11 '14 at 03:41
  • 1
    Sometimes it happens that you want to retrieve the PID of a Java based service in a machine running multiple Java based services. In this case it seems to me only the AWK approach gives a result, even though the original question didn't mention this scenario. – danidemi Nov 12 '14 at 17:19
16

jps is the same as ps except it only looks at java processes.

If you then need the PID, you can do something like the following:

jps | grep JAVA_NAME | awk '{print $1}'

That runs jps, then uses grep to filter by the java application or jar you want to kill. After that, awk captures and prints just the pid to the console.

Jesan Fafon
  • 2,234
  • 1
  • 25
  • 29
  • It happened to me once that jps was not available from the command line. But if it is, I really prefer this approach. – danidemi Nov 12 '14 at 17:21
  • The best solution if you want to script this out ;) – Daniel Andrei Mincă Apr 27 '17 at 12:46
  • we WERE using jps but had to use ps again! it is depending on information in dir `/tmp/hsperfdata_$USER` which in our case got lost several times when `/tmp` was cleaned up by automatic processes. that's why are going back to something along `local PID=$(ps -C java -o pid,cmd | grep $JAR_FILE | awk '{print $1}')` – hotzen Apr 13 '18 at 18:29
  • This worked great for me for a process started like this: `java -jar application/target/application-0.9.0.jar` Then `jps | grep application-0.9.0.jar | awk '{print $1}'` --> returns PID :) – Wlad Nov 18 '19 at 13:04
9

A simple way is to run this:

pgrep java
Eusuf Kanchwala
  • 149
  • 1
  • 4
  • 1
    This one is good in my case, too - since I have only one java process to deal with. But what if you have more than one java process? – Wlad Nov 18 '19 at 13:06
  • 1
    There are tons of ways to do so! you can either use jps or ps commands and go nuts using grep to filter out unwanted results to your heart's content. There are virtually no limitations. just do jps/ps ef| grep "Your search term". pgrep is not suitable for differentiating among multiple processes of same type so you'll have to use jps or ps. – Eusuf Kanchwala Jul 02 '20 at 01:14
  • use -f for exact match e.g: `pgrep -f "java -jar app-1.0.0.jar" | xargs kill` – Ujjwal Singh Nov 02 '21 at 19:07
0
ps -ef | grep java | grep MpiPageRank | grep -v grep | awk '{print $2}'

This will return exact pid of the MpiPageRank out of all java processes running   
ps -ef --> Returns all active processes
grep java --> Filter only java processes from all active processes
grep MpiPageRank --> Select only process related to MpiPageRank         
grep -v grep --> Remove the process related to Grep   
awk '{print $2}' --> select 2nd part of selected line
pratap
  • 538
  • 1
  • 5
  • 11