Bash regex parsing ss output

560 views Asked by At

I'm trying to use a bash regex from a ss comand output to extract the name of the application that is using a given port in a function. I have some problems with the regex.

Command to check the data is ss -tupln

Example of data to parse (ipv4):

tcp    LISTEN   0        10                0.0.0.0:80          0.0.0.0:*    users:(("nc",pid=3474,fd=4))          
tcp    LISTEN   0        10                   [::]:80             [::]:*    users:(("nc",pid=3474,fd=3))  

In this case I want to extract nc which is the name of the program using the port

Example of data to parse (ipv6):

tcp   LISTEN 0      511                 *:80              *:*    users:(("apache2",pid=6741,fd=4),("apache2",pid=6740,fd=4),("apache2",pid=6738,fd=4),("apache2",pid=6737,fd=4),("apache2",pid=6736,fd=4),("apache2",pid=6724,fd=4))

In this case I want to extract apache2 which is the name of the program using the port.

I need a general regex valid for both cases. I don't care if it is get using grep or if is done using pure bash regex. My non-working approach:

#!/bin/bash

get_name() {
    local regexp="${1}.*[0-9\*]:${2}[[:blank:]]+.*[[:blank:]]+users:\(\(\"(.+)\"\,"

    [[ $(ss -tupln) =~ ${regexp} ]] && process_name="${BASH_REMATCH[1]}" 

    echo "${process_name}"
}
get_name "tcp" "80"

Thanks.

2

There are 2 answers

2
The fourth bird On BEST ANSWER

You might use gnu grep:

ss -tupln | grep -oP 'tcp\h.*?:80\h.*?\busers:\(\("\K[^"]+(?=")'

The pattern matches:

  • tcp\h Match tcp and a space
  • .*?:80\h Match as least as possible chars and then :80 and a space
  • .*?\busers: Match as least as possible chars and then users:
  • \(\(" match (("
  • \K[^"]+ Forget what is matched to far (it will not be part of the resulting match)
  • (?=") Positive lookahead, assert = directly to the right

See a regex demo

0
Arkadiusz Drabczyk On

You can use awk like that:

$ ss -tupln | awk -v proto=tcp -v port=80 '$1 == proto && $5 ~ ":" port "$" {split($0, array, "\""); print array[2]}'
apache2