2

我正在尝试使用ss命令输出中的 bash 正则表达式来提取在函数中使用给定端口的应用程序的名称。我对正则表达式有一些问题。

检查数据的命令是ss -tupln

要解析的数据示例(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))  

在这种情况下,我想提取nc哪个是使用端口的程序的名称

要解析的数据示例(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))

在这种情况下,我想提取apache2哪个是使用端口的程序的名称。

我需要一个对这两种情况都有效的通用正则表达式。我不在乎它是使用 grep 还是使用纯 bash 正则表达式完成。我的非工作方法:

#!/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"

谢谢。

4

2 回答 2

1

你可以awk这样使用:

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

您可能会使用 gnu grep:

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

模式匹配:

  • tcp\h匹配 tcp 和一个空格
  • .*?:80\h匹配尽可能少的字符,然后:80和空格
  • .*?\busers:匹配尽可能少的字符,然后users:
  • \(\("匹配(("
  • \K[^"]+忘记与 far 匹配的内容(它不会成为结果匹配的一部分)
  • (?=")=正向前瞻,直接向右断言

查看正则表达式演示

于 2021-10-07T17:57:48.807 回答