tags:

views:

54

answers:

4

Hi,

I am trying to do some process control in a script (bash). For this reason I output the process group id of the current process to a file.

ps ax -o '%p %r'|perl -ne 'if ($_ =~ /\s*$$\s*(\d+)/) { print "$1"; exit; }' > $pgidfile
nohup $JAVA_HOME/bin/java -cp somejar.jar some.java.Program & > /dev/null 2>&1

I have also tried:

ps ax -o '%p %r'|awk '/'"$$"' [0-9]+/ {print $2}' > $pgidfile
nohup $JAVA_HOME/bin/java -cp somejar.jar some.java.Program & > /dev/null 2>&1

However in both these cases, the file (in $pgidfile) seems to be empty. (Although on certain rare occasions it does seem to have the correct value.) Also, just running the commands(to output the process group id - option 1 or option 2 above) themselves on the commandline seem to do the right thing.

It would be great if someone could suggest a solution to the above problem or answer either (or both) of the following questions:

1) What is the suggested way to get a process's group id in a shell or perl script?

2) Does running a command under nohup change the output redirection of previous/subsequent commands that aren't related to the command executed with nohup?

A: 

Instead of resorting to awkward shell scripting and ps, why don't you have your Java program get its own pgid? In the worst case, you can do this in a one-line JNI method.

Borealid
A: 
ps ax -o '%p %r' | awk -vp=$$ '$0~p{print $2}'
ghostdog74
I think you want `awk -vp=$$ '$1==p{print $2}'`, lest $$ := 123 match records with PID 51230 or PGID 4123.
pilcrow
A: 

In Perl, you can get a process's real group id with $(, and its effective group id with $(. See perldoc perlvar.

Ether
Correction: effective group is `$)`. Also, this is not what the OP is asking about (process groups - PGID). Your answer is about a process's group memberships (GID).
Dennis Williamson
A: 

1) What is the suggested way to get a process's group id in a shell or perl script?

An improvement to your current approach would be to do an exact field match on the PID you care about. Any unanchored regex technique (such as your original post) runs the risk of matching the wrong thing. If $$ happens to be 123, you'll match ps output lines for PIDs 1123, 1234, etc.

Now, awk and perl are both very good at processing field delimited input (see perl's -a switch), but you don't need to do that, since you can limit ps to just the process you care about:

$ ps -o '%r' $$ | tail -n 1 > $pgfile

Find out how your ps can be told to omit headers, and you can remove tail from that pipeline.

2) Does running a command under nohup change the output redirection of previous/subsequent commands that aren't related to the command executed with nohup?

No. Something else is amiss in your scenario.

pilcrow
Thanks everyone for your responses. I used pilcrow's suggestion (or a slight variant: ps -o pgrp= $$, which suppresses the header) and so accepted his answer - I suppose the other approaches are valid answers too.
decimus phostle