I use ps -ef | grep catalina | grep -v grep to print the tomcat process running on the system:

kshitiz   7099     1  0 May11 ?        00:02:29 /usr/lib/jvm/jdk1.8.0/bin/java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:38156 -Dcatalina.base=/home/kshitiz/Documents/workspaces/ggts/.metadata/.plugins/org.eclipse.wst.server.core/tmp1 -Dcatalina.home=/opt/tomcat-7.0.42 -Dwtp.deploy=/home/kshitiz/Documents/workspaces/ggts/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps -Djava.endorsed.dirs=/opt/tomcat-7.0.42/endorsed -Dfile.encoding=UTF-8 -classpath /opt/tomcat-7.0.42/bin/bootstrap.jar:/opt/tomcat-7.0.42/bin/tomcat-juli.jar:/usr/lib/jvm/jdk1.8.0/lib/tools.jar org.apache.catalina.startup.Bootstrap start

Then I use ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}' to extract the process id:


But when I alias the whole command alias tomcat_id="ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}'" and use it via alias, it prints the whole text and awk doesn't seem to work.

type tomcat_id gives:

tomcat_id is aliased to `ps -ef | grep catalina | grep -v grep | awk -F' ' '{print }''
  • 2
    You might want to look at using pgrep if your system supports it - or, failing that, doing the match in awk to save the extra calls to grep. If you must use grep, there's a regex trick grep [c]atalina that should allow you to remove the grep -v grep (which you can also use in awk for the same reason i.e. awk '/[c]atalina/ {print \$2}'). – steeldriver May 12 '14 at 12:48

A general rule of aliases: if it gets too complex for an alias, use a function instead.

tomcat_id () {
  ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}'

The problem with your alias definition is that you got the quoting wrong. The line that defines the alias is a shell command and is parsed by the shell. Since you used double quotes, and there are probably no positional parameters at the time (so $2 expands to an empty string), the alias you've defined is

ps -ef | grep catalina | grep -v grep | awk -F' ' '{print }'

The easy way to define an alias is to use single quotes for the definition, and avoid using single quotes in the aliased command. While I'm at it, I've removed -F " ", which is the default anyway (and a bit weird because it looks like “a space” but means “any sequence of whitespace”).

alias tomcat_id='ps -ef | grep catalina | grep -v grep | awk "{print \$2}"'

Or you can use '\'' to effectively quote a single quote inside a single-quoted literal.

alias tomcat_id='ps -ef | grep catalina | grep -v grep | awk '\''{print \$2}'\'

But, as I wrote above, use a function, it's clearer. Or rather, use the appropriate tool for the job:

alias tomcat_id='pgrep catalina'


alias tomcat_id='pidof catalina'

Gnouc's answer is perfectly valid (which is why I upvoted it), but I'd like to offer an alternative:

alias tomcat_id="ps -ef|awk '\$8 ~ /java/ && /catalina/ {print \$2}'"

the idea here is that in the process name (field 8) we should be able to find java and on the line as a whole we should find catalina.

So we let awk do all the work of matching and printing. No need to bother grep ;)

So the meaning:

$8 ~ /java/ && /catalina/ {print $2}

is match field $8 against regex /java/ and match the whole line (could also use $0 explicitly) against regex /catalina/ and if those things are true, print field $2. Remember what was already stated in Gnouc's answer: the default separator is a blank space already. No need to define this.


You must escape the dollar sign in awk command:

alias tomcat_id="ps -ef | grep catalina | grep -v grep | awk '{print \$2}'"

And you don't have to use -F' ', awk use spaces as default field separate.

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.