19

The postfix daemon has only the name "master" if I use netsat like this:

root@myhost# netstat -tulpen| grep master tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 53191445 13640/master 

If I use ps I get a more verbose name:

root@myhost# ps aux| grep 13640 root 13640 0.0 0.0 25036 1500 11:35 0:00 /usr/lib/postfix/master 

Is there a way to tell netstat to output the long name?

In this case it would be /usr/lib/postfix/master.

Update

It seems that netstat can't do it. If you know how to do this with an other tool, then this is valid question, too. (But netstat based solutions are still prefered).

Update2

All answers work. Thank you very much for showing your unix knowledge. But up to now the answers are far too long/complicated.

Is there no easy solution? I can install any tool which is needed, but I want the usage to be simple to use.

I can't give the bounty to all of you ...

There are several answers which to post processing to get the needed information. Each answer uses a different way and I don't see that one solution is better than an other.

Unfortunately there seems to be no unix/linux which can do this out of the box. But that's not the fault of you, who tried to help me.

Unfortunately I can't give the bounty to all answers :-)

I gave the bounty to the user with the least reputation points.

6
  • Use lsof instead. Commented Oct 12, 2016 at 10:44
  • @SatoKatsura during the last years I mostly used netstat. Are there any other good reasons to switch? Up to now this question is the first feature I am missing. Commented Oct 17, 2016 at 6:31
  • Who said anything about switching. lsof has lots of features. On the other hand netstat is OS-dependent, and its features don't completely overlap with those of lsof. You should use both when appropriate. Commented Oct 17, 2016 at 6:57
  • I am not sure if it is possible to see the full command line in netstat. I think it is reading the file /proc/13640/comm, and that is only showing the "master" name Commented Oct 18, 2016 at 8:33
  • 1
    If you use Linux, please not that netstat is deprecated in favor of ss. It has the same limitation as you point out, however. Commented Oct 20, 2016 at 23:59

6 Answers 6

10

This is the most interesting search for an "elegant" solution I've had in some time. Thank you.

General comment:

Rather than parsing /proc/pid/cmdline, it makes much more sense to run readlink /proc/pid/exe instead.

What it looks like:

I set up a shell function full to abstract the complexity out of this—mostly just to save on typing.

The only dependencies are POSIX-compliant ex and Linux standard readlink.

In the following terminal output I have piped through head for brevity.

[root@localhost ~]# netstat -tulpen | head Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 9581 1237/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 10164 1493/master tcp 0 0 0.0.0.0:555 0.0.0.0:* LISTEN 0 14326 2824/nc tcp 0 0 0.0.0.0:46638 0.0.0.0:* LISTEN 29 8848 960/rpc.statd tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 8749 940/rpcbind tcp 0 0 :::22 :::* LISTEN 0 9583 1237/sshd tcp 0 0 ::1:25 :::* LISTEN 0 10166 1493/master tcp 0 0 :::47166 :::* LISTEN 29 8856 960/rpc.statd [root@localhost ~]# netstat -tulpen | head | full Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 9581 1237/usr/sbin/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 10164 1493/usr/libexec/postfix/master tcp 0 0 0.0.0.0:555 0.0.0.0:* LISTEN 0 14326 2824/usr/bin/nc tcp 0 0 0.0.0.0:46638 0.0.0.0:* LISTEN 29 8848 960/sbin/rpc.statd tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 8749 940/sbin/rpcbind tcp 0 0 :::22 :::* LISTEN 0 9583 1237/usr/sbin/sshd tcp 0 0 ::1:25 :::* LISTEN 0 10166 1493/usr/libexec/postfix/master tcp 0 0 :::47166 :::* LISTEN 29 8856 960/sbin/rpc.statd [root@localhost ~]# 

It also works with any form of netstat -p, even the forms that have other trailing data on some lines:

[root@localhost ~]# netstat -p | head Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 10.0.2.15:ssh 10.0.2.2:63550 ESTABLISHED 2557/sshd Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 11 [ ] DGRAM 8584 895/rsyslogd /dev/log unix 2 [ ] DGRAM 9124 1045/hald @/org/freedesktop/hal/udev_event unix 2 [ ] DGRAM 7116 340/udevd @/org/kernel/udev/udevd unix 2 [ ] DGRAM 16523 3537/pickup unix 2 [ ] DGRAM 15036 2865/su [root@localhost ~]# netstat -p | head | full Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 10.0.2.15:ssh 10.0.2.2:63550 ESTABLISHED 2557/usr/sbin/sshd Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 11 [ ] DGRAM 8584 895/sbin/rsyslogd /dev/log unix 2 [ ] DGRAM 9124 1045/usr/sbin/hald @/org/freedesktop/hal/udev_event unix 2 [ ] DGRAM 7116 340/sbin/udevd @/org/kernel/udev/udevd unix 2 [ ] DGRAM 16523 3537/usr/libexec/postfix/pickup unix 2 [ ] DGRAM 15036 2865/bin/su [root@localhost ~]# 

How it's defined:

[root@localhost ~]# type full full is a function full () { ex -c 'g/^.*\(\<[0-9]\+\)\/.*$/ya|pu|s::readlink /proc/\1/exe:|.!sh' -c 'g/^\//-ya|pu|-2s/^\(.*\<[0-9]\+\)\/[^[:space:]]*\(.*\)$/\1/|+2s//\2/|-2j!3' -c%p -c 'q!' /dev/stdin } [root@localhost ~]# 

How it works (step by step breakdown):

(Forthcoming; in the meantime try it out and let me know how you like it.)

2
  • holy regex wildness batman! Commented Jun 10, 2019 at 19:44
  • @javadba, no kidding. If you'd like that "forthcoming" breakdown I can oblige, though. :) Commented Jun 10, 2019 at 21:04
5

As you already figured netstat by default cannot provide full cmdline output with -p option. As per source it seem to limited to 20 chars and only lists portion of the full cmdline

You could write your own wrapper around netstat to display full details. Added below snippet of python code which displays full cmd line.

#!/usr/bin/env python from subprocess import Popen,PIPE out,err = Popen(['netstat','-antlp'],stdout=PIPE).communicate() for l in out.splitlines(): line = l.split() if '/' in line[-1]: p = line[-1].split('/')[0] line[-1] = str(p) + ' -> ' + open('/proc/'+p+'/cmdline','r').readline().split('-')[0] print '\t'.join(line) 

Sample output:

$ sudo ./netstat.py Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:11443 0.0.0.0:* LISTEN 4007 -> /usr/sbin/apache2 tcp 0 0 192.168.2.125:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 172.17.0.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 192.168.125.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 192.168.0.200:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3125 -> /usr/sbin/sshd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 30845 -> /usr/sbin/cupsd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3884 -> /usr/sbin/exim4 tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named tcp 0 0 0.0.0.0:32765 0.0.0.0:* LISTEN 3014 -> /sbin/rpc.statd tcp 0 0 0.0.0.0:8895 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 0.0.0.0:23423 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 0.0.0.0:32767 0.0.0.0:* LISTEN 3827 -> /usr/sbin/rpc.mountd tcp 0 0 0.0.0.0:23424 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:23523 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 0.0.0.0:23524 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 192.168.0.200:44331 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3002 -> /sbin/rpcbind tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 4007 -> /usr/sbin/apache2 tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 3908 -> /usr/bin/Xorg:0 

You could write your own wrapper around similar lines and add to your toolbox!

4
+50

Just to have fun I made this:

sudo netstat -putan | awk '/master/ {out=""; for(i=1;i<=6;i++){out=out" "$i}; split($7,result,"/"); system("ps aux | grep -v grep | grep " result[1] " >> x&"); getline < "x"; print out " " $14}' 

I think is what you want. You can always use it as an alias, to simplify its use.

Explanation:

The next line gets the output of netstat and it filters master

sudo netstat -putan | awk '/master/ 

The next line stores the output of netstat.

out=""; for(i=1;i<=6;i++){out=out" "$i} 

The next line gets the pid:

split($7,result,"/") 

The next line gets the full name from ps aux and it prints everything

system("ps aux | grep -v grep | grep " result[1] " >> x&"); getline < "x"; 

Finally it is printed:

print out " " $14 
4
  • 1
    Having fun is important. "Just for fun" is the title of the book by Linus Torvalds :-). Thank you for this answer. Commented Oct 18, 2016 at 15:26
  • 1
    Simpler: | awk '/master/ { split($7,result,"/); NF=6; save=$0; "ps hp" result[1] | getline; print save,$5 }' Commented Oct 21, 2016 at 8:37
  • Agree with @dave_thompson_085; don't use grep -v grep in a script (only interactively). Instead, actually learn and correctly use the flags to ps to get the actual results you want. Commented Oct 24, 2016 at 8:20
  • the python solutuon is more readable and more generic, versatile Commented Aug 6, 2018 at 21:46
2

Use the Linux tool lsof. But it may not be installed on some Unix flavours.

lsof -i tcp | grep -w "pid" 
1

Similar solution to @iñaki-murillo but using /proc/pid/cmdline instead of ps and grep. I also use $NF and assume the last field is in pid/procname format rather than assume that it is $7 (It was actually $6 on my system).

netstat -putan|awk '/master/ {split($NF, pid,"/");sub(FS $NF,x);getline cmd < ("/proc/"pid[1]"/cmdline");print $0" "pid[1]"/"cmd}' 

Explanation

/master/ Filter on lines containing master.

split($NF, pid,"/"); Split the last field on / and store in pid

sub(FS $NF,x); Delete the last field.

getline cmd < ("/proc/"pid[1]"/cmdline") Read the command line call of the pid in question and save it in cmd.

print $0" "pid[1]"/"cmd Print it all out

0

With xargs & readlink:

$ netstat -tulpen \ | grep chrome \ | xargs -L1 bash -c 'echo $@ $(readlink /proc/${7//[A-Z\/]/}/exe)' 0 0 0.0.0.0:5353 0.0.0.0:* 1000 17007 2521/chrome /opt/google/chrome/chrome 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.