Get opened port with given PID?

i want to get tomcat listening port , from a command.

ps -ef | grep catalina | grep -v "grep catalina" | grep -v "catalina.out" | awk '{print $2}' | head -1

output : 
-----
1234

Now with this 1234 i need to know , in which port my tomcat is running...

i tried ,

netstat -ao | grep "1234"
lsof -p 1234
fuser 8080/tcp

will give the exact output with pid.

But i need pid as input and port as output

is there any other way ?

What do you mean by

??

Do you want to write an interactive script with some read commands or... ? What do you mean by input and output? For which tool/script is this input/output?
Please explain what you want to achieve, thanks.

i am sorry if its my mistake.

My need is to get tomcat listening port through a shell script.

You can it do the way you already did or check the server.xml of your Tomcat where the ports are defined in and grep it out of there. When having the port(s), you can just check additionally with

netstat -an| grep <port>

if it is up and running.
The way you have chosen, you do not know how many Tomcat installations/configurations are there, but just check which is up and try to get it's port.
It depends which way you want to go.

You should be able to grep the port tomcat is listening on from the output of lsof

Dear shamrock, i tried as you told

[root@linux ~]# lsof | grep 8080
automount  2867      root  mem       REG       8,11      98080    1006186 /usr/lib/autofs/lookup_file.so

And zaxxon, what you told is correct only. I can get it from server.xml file.
But my problem is : we have to use this script in a number of servers. And the server.xml file may be manually edited. There will be http & https connections also. The part <Connector port="portNum" will edit manually. And there is a chance to change the alignment also.

[root@linux ~]# grep 8080 /tomcat6/apache-tomcat-6.0.18/conf/server.xml
         Define a non-SSL HTTP/1.1 Connector on port 8080
    <Connector port="8080" protocol="HTTP/1.1" 
               port="8080" protocol="HTTP/1.1"

So upto my knowledge , there is only one way , that to GET the PORT number from PROCESS id.

[root@linux ~]# ps -ef | grep tomcat
root      7976     1  0 Jul18 ?        00:22:11 /usr/java/jdk1.6.0_13/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/tomcat6/apache-tomcat-6.0.18/conf/logging.properties -verbose:gc -XX:+PrintGCDetails -XX:MaxPermSize=512M -Xms1024M -Xmx1024M -Djava.awt.headless=true -XX:+UseParallelOldGC -XX:+UseParallelGC -Djava.endorsed.dirs=/tomcat6/apache-tomcat-6.0.18/endorsed -classpath :/tomcat6/apache-tomcat-6.0.18/bin/bootstrap.jar -Dcatalina.base=/tomcat6/apache-tomcat-6.0.18 -Dcatalina.home=/tomcat6/apache-tomcat-6.0.18 -Djava.io.tmpdir=/tomcat6/apache-tomcat-6.0.18/temp org.apache.catalina.startup.Bootstrap start
root     28214 28183  0 10:02 pts/1    00:00:00 grep tomcat

[root@linux ~]# ps -ef | grep catalina | grep -v "grep catalina" |  grep -v "catalina.out"|awk '{print $2}' | head -1
7976

[root@linux ~]# fuser 8080/tcp
8080/tcp:             7976       -->> I need vice-versa of this. That is , by giving process id , i should get port number. I tried by grep of fuser but i couldn't find.

Shamrock's idea is correct and good. The only difference is, that if you want an absolute list of ports of configured ports (not only those that are currently up and running), you will not get it by checking which processes are there, since it could be, that one of them is down for maintenance or similar.
For the problem of the format the server.xml could be in due to manual editing, I would try to run following via ssh from one box that has hopefully access to all others so you don't have to log in into each of them. For stuff like this I usually do something like the following (of course depending they are in a similar directory - else you have to think about how to find those server.xml in different locations):

$> cat server.list
server_1
server_2
server_3
$> while read S; do ssh -n -o "ConnectTimeout=3" -o "BatchMode yes" $S "cat ~tomcat/conf/server.xml" | sed -n 's/.*Connector port="\([^"]*\)" .*/\1/p'

On a box where 3 instances of Tomcat are running, I get something like:

8080
8443
8444
8445
8446
8447
8009

Which are up and running you could get the other way with ps and lsof.

Sadly I have problems with my edit function so here an addition to make the code work. I forgot to end the line with:

....ctor port="\([^"]*\)" .*/\1/p' ; done < server.list

thanks zaxxon for this idea..

$> cat server.list
192.168.1.10

but one error

[me@linux ~]$ while read S; do ssh -n -o "ConnectTimeout=3" -o "BatchMode yes" $S "cat /tomcat6/apache-tomcat-6.0.26/conf/server.xml" | sed -n 's/.*Connector port="\([^"]*\)" .*/\1/p'  ; done < server.list
Permission denied (publickey,gssapi-with-mic,password).

can i tell one another idea..

gives the output as
INFO: Deploying web application directory docs
Jul 21, 2011 9:56:27 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Jul 21, 2011 9:56:27 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jul 21, 2011 9:56:27 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jul 21, 2011 9:56:27 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/25 config=null
Jul 21, 2011 9:56:27 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 18838 ms
--
INFO: Deploying web application directory docs
Jul 21, 2011 12:12:16 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Jul 21, 2011 12:12:16 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jul 21, 2011 12:12:16 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jul 21, 2011 12:12:16 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/31 config=null
Jul 21, 2011 12:12:16 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 17808 ms
--
INFO: Deploying web application directory docs
Jul 21, 2011 12:38:59 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Jul 21, 2011 12:38:59 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jul 21, 2011 12:38:59 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jul 21, 2011 12:38:59 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/23 config=null
Jul 21, 2011 12:38:59 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 21409 ms

grep "`date +"%b %d"`"

will give the date started..

but i don't know how to code exactly this..

---------- Post updated at 01:44 PM ---------- Previous update was at 01:23 PM ----------

zaxxon ,

In this script i have to ssh each time the script is running. am i right ?

here actually one problem is there.

i am sorry that i did't give the complete spec.

The thing is:

  1. i will create a shell script to get port number of tomcat , running or not , some other server info..etc and append the output to a file_details

  2. I will put this script in each of our servers (say 10 servers)

  3. And i will get the info from file_details whenever i need.

The while loop will cycle through the lines of the input file, where on each line is the name or IP-address of a single host to be inspected. So 10 lines will be 10 ssh connects, one to each host.

If you deploy that script on each host, you'll have to ssh to each one though to get the information. There are different ways to achieve what you want - you could also run that script via cron on each box and have them connect to your central box delivering the info to it in intervals or once a day, whatever.

But to have passwordless communication with ssh between the hosts and your central collection box, you would have to create passwordless ssh-keys and exchange the public ssh keys to your needs.

1 Like

thanks zaxxon for your fast reply..

But what about this..

Like this?

awk '/^INFO: Starting/ {sub(/\/1.1/,"",$4); a=$1 FS $2 FS $3 FS $4; split($NF,arr,"-"); b=arr[2]; getline; sub(/,$/,"",$2); print $1,$2,a,b}' infile
Jul 21 INFO: Starting Coyote HTTP 8080
Jul 21 INFO: Starting Coyote HTTP 8080
Jul 21 INFO: Starting Coyote HTTP 8080

Or without a split, just deleting .*-:

awk '/^INFO: Starting/ {sub(/\/1.1/,"",$4); a=$1 FS $2 FS $3 FS $4; sub(/.*-/,"",$NF); b=$NF; getline; sub(/,$/,"",$2); print $1,$2,a,b}' infile
1 Like

Thanks a lot.. for this Great work..

Thanks...

i made it like this..

cat `echo $CATALINA_HOME/logs/catalina.out` | grep -B10 "INFO: Server startup in" | awk '/^INFO: Starting/ {sub(/\/1.1/,"",$4); a=$1 FS $2 FS $3 FS $4; split($NF,arr,"-"); b=arr[2]; getline; sub(/,$/,"",$2); print $1,$2,a,b}' | tail -1 | awk '{print $7}' | uniq

output:
8080

---------- Post updated at 04:35 PM ---------- Previous update was at 04:21 PM ----------

got one more.. which gives all ports for tomcat , server listens..

netstat -anp | grep `ps -ef | grep catalina | grep -v "grep catalina" | grep -v "catalina.out" | awk '{print $2}' | head -1`  | grep LISTEN | awk '{print $4}'  | awk -F: '{print $NF}'

Thanks for feedback - other people will benefit from your code :slight_smile: