6

I'm running a few different services via mono, each on there own port, but when I use netstat to check which have assigned a port and which haven't, all I get are 2 processes called "mono", no way to tell which is which, apart from looking at the port, which can sometimes change.

Is it possible to get netstat to show the "command" for each port, like htop does for processes?

This way I can tell what process is which.

1 Answer 1

3

It has taken a bit of doing, but I've managed to create a filter to append the program's parameter list:

netstat -p | while l="$(line)";\
  do p="$(sed -En 's/^.*( [0-9]+)\/[^ ]*.*/\1/gp'<<<"$l")";\
     [ "$p" == "" ] || p=" ## $(ps -p $p -o cmd=)";\
     echo "$l"$p;\
  done

Notes:

  • Obviously you will not type this each time: put the filter code into a function or script (in which case the trailing ;\ strings are unnecessary).
  • Because of buffering when netstat writes to a pipe, there is a delay before the filter starts processing lines.
  • For the same reason, there is the possibility that the program will terminate or exec another between when netstat outputs the line and ps retrieves the arguments for the PID.
  • The program path will not displayed if it was not specified when the program was run, since ps shows arg0 from the program's run string.
  • Not all systems have the line command: if you replace while l=($line) with the more usual while read -r l, this will trim leading and trailing spaces; when you need to retain them, you can use while read -r, with $REPLY replacing $l (or while read -r; do l="$REPLY"; ... for an exact equivalent, with $l unchanged).
  • The filter works by reading a line from netstat, using sed to extract the PID from any number/string sequence, then using ps -p on this PID to find the command parameters.
  • In the final echo "$l"$p, the $p is outside the quotes: this is to delete trailing blanks (also a problem with wine programs), but it will have the side-effect of compressing multiple spaces in parameters to a single space.
3
  • 1
    read -r reads the backslashes. To check use of port you probably only want TCP, probably want LISTEN as well as or instead of ESTABLISHED, and maybe don't need names so -tanp or -tlnp. Since PID/Prog field is last you could read -ra a then use ${a[${#a[@]}-1]} but I'd rather use awk like netstat...| awk '{p=$NF} sub(/\/.*/,"",p) {x=$0; "ps -p"p" -ocmd=" |getline; $1=$1; print x,$0}' where $1=$1 compresses and trims whitespace; to only trim from end sub(/ *$/,""). May 26, 2016 at 5:39
  • @dave_thompson_085 - Thanks for your thoughtful comment, and particularly for pointing out read -r: I'll update my answer. I assumed that other netstat options would be used, but I was concentrating on the filter, and used netstat -p to check my filter on all the different record formats that are output, which include records where the PID/name sequence is not at end of line. I guess it's a matter of familiarity, but I am more used to using bash expansion or sed for the sort of filtering you are doing with awk.
    – AFH
    May 26, 2016 at 13:33
  • Note that in any recent Bash (4.2.46) you get -bash: line: command not found so maybe the note is not enough for general purpose. Aug 30, 2021 at 15:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .