I'm trying to write a little diagnostic tool and one of the functions I want from it is that I want to run is:

ps axu | grep tomcat | grep -v grep | awk '{ print $<list of desired fields> }'  

I want to return the userid that started tomcat and the following parameters that were passed when tomcat started:

-javaagent:/usr/share/tomcat7/<someagent> -Dcatalina.base=/var/lib/tomcat7 
- Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp

I want those fields passed into an array which I can then use to tell the user something about the tomcat install.

The problem is I can't find a way of formatting the command to force the fields to be what I need them to be to make awk work.

At this point I'm thinking of just taking the output, writing it to a temp file, then pulling what I want out using regex.

I know there's a way to do this in Bash but I have not had any success getting there from here.

  • It needs to be from ps output? – Braiam Aug 10 '14 at 23:49
  • I should clarify something. This is a tech support tool that will be provided to customers and so I can't know in advance what form of *NIX they'll be running ahead of time. It occurred to me that there's another way to get at it. Since this is meant to be used by other IT people I thought I could just build a menu and just ask them for their OS which I could then pass the appropriate ps command for. If that is a worse idea than the one before, let me know. I appreciate the feedback y'all have given me so far. It's been invaluable. – Adrienne Davis Aug 11 '14 at 0:14
  • @AdrienneDavis Don't ask the user to do something that can easily be done automatically! You can detect the OS automatically — but you don't need to, you can just stick to standard features (as I do in my answer). – Gilles 'SO- stop being evil' Aug 11 '14 at 7:19

Pass the -o option to ps to control which fields it outputs. If you add an = sign after all the fields, then the header line is omitted.

Use -e instead of ax to stick to standard features (this will work on any non-antique unix).

Your filter with grep is not robust. For example, if you run this command from a script called look-for-tomcat, then your script would be matched as well. Here's a more robust way that looks for a JVM process with org.apache.catalina.startup.Bootstrap as an argument.

ps -e -o user=,args= | awk '
    $2 ~ /java$/ &&  / org\.apache\.catalina\.startup\.Bootstrap($| ) {
        print "user name: ", $1;
        if (match($0, / -javaagent:[^ ]* /)) print substr($0, RSTART+1, RSTART+RLENGTH-2);
        # etc.

Even better would be to log the PID of the tomcat process in a file (e.g. /var/run/tomcat.pid) when it starts.


If you have /proc on your particular flavor of *nix, you may try to coax the data you want out of that instead. I think this may be a bit saner than attempting to wade through the tedium of parsing output that is meant for a human to read.

For example, to get the user ID that started the tomcat process, you can do:

stat -c'%u' /proc/$(pgrep tomcat)/

Relying on the availability (and standardization) of /proc may be even more of a hassle depending on your particular application/environment/... It's up to you to decide, I guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.