过滤netstat输出以获取bash中的特定端口

时间:2017-11-05 00:37:46

标签: linux bash awk port netstat

我正在使用命令sudo netstat -tulpn获取运行Ubuntu Server 16.0.4的计算机上所有已打开端口的列表

这是输出:

user@myServer:~/Skripte$ sudo netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      1319/dovecot
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      1319/dovecot
tcp        0      0 192.168.1.22:53         0.0.0.0:*               LISTEN      1147/named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      1147/named
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1167/sshd
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      2644/postgres
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      1902/master
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      1147/named
tcp6       0      0 :::9090                 :::*                    LISTEN      951/java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1203/java
tcp6       0      0 :::9001                 :::*                    LISTEN      948/java
tcp6       0      0 :::8009                 :::*                    LISTEN      1203/java
tcp6       0      0 :::3306                 :::*                    LISTEN      1289/mysqld
tcp6       0      0 :::110                  :::*                    LISTEN      1319/dovecot
tcp6       0      0 :::143                  :::*                    LISTEN      1319/dovecot
tcp6       0      0 :::8080                 :::*                    LISTEN      1203/java
tcp6       0      0 :::80                   :::*                    LISTEN      1717/apache2
tcp6       0      0 :::8083                 :::*                    LISTEN      950/java
tcp6       0      0 :::53                   :::*                    LISTEN      1147/named
tcp6       0      0 :::22                   :::*                    LISTEN      1167/sshd
tcp6       0      0 :::5432                 :::*                    LISTEN      2644/postgres
tcp6       0      0 :::25                   :::*                    LISTEN      1902/master
tcp6       0      0 ::1:953                 :::*                    LISTEN      1147/named
tcp6       0      0 :::443                  :::*                    LISTEN      1717/apache2
udp        0      0 192.168.1.22:53         0.0.0.0:*                           1147/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           1147/named
udp        0      0 0.0.0.0:68              0.0.0.0:*                           1066/dhclient
udp6       0      0 :::53                   :::*                                1147/named

现在,我尝试编写脚本 getPorts.sh [可选搜索参数] ,它将打印所有端口(如果没有提供参数),或者它只会打印在过滤器中使用的端口。但是,netstat打印出了许多我不需要的信息,所以我希望我的脚本可以过滤这个文本,只提供我感兴趣的两个信息:端口和PID /程序名称

基本上,我想要这种行为:

user@myServer:~/Skripte$ ./getPorts.sh java
9090 951/java
8005 1203/java
9001 948/java

user@myServer:~/Skripte$ ./getPorts.sh 8080
8080 1203/java

user@myServer:~/Skripte$ ./getPorts.sh
110 1319/dovecot
143 1319/dovecot
53  1147/named
53  1147/named
22  1167/sshd
5432    2644/postgres
25  1902/master
953 1147/named
9090    951/java
8005    1203/java
9001    948/java
8009    1203/java
3306    1289/mysqld
110 1319/dovecot
143 1319/dovecot
8080    1203/java
80  1717/apache2
8083    950/java
53  1147/named
22  1167/sshd
5432    2644/postgres
25  1902/master
953 1147/named
443 1717/apache2
53  1147/named
53  1147/named
068 1066/dhclient
53  1147/named

我写了以下脚本:

#/bin/bash
filter=${1:-""}
zacasna=$(sudo netstat -tulpn | tr -s ' ' | cut -d ' ' -f 4,6,7 | tr ' ' '\t' | column -t | grep "$filter")
echo "$zacasna"

这个脚本接近我想要做的,但是它打印状态列,我不想要(因为那些缺少某些信息的最后一行)并且它打印数据非常粗暴的状态。

我正在考虑使用awk,但我无法正确使用它来实现这一目标。

2 个答案:

答案 0 :(得分:1)

由于netstat具有固定的列宽,因此最简单的解决方案是使用cut -cN-M,例如:

#/bin/bash
filter=${1:-""}
netstat -tulpn | cut -c21-44,81- | grep "$filter"

另一种方法是将tcpudp分开,并为每个使用不同的列号。使用awk,您可以这样做:

netstat -tulpn | awk -vOFS='\t' '/^tcp/{print $4,$7} /^udp/{print $4,$6}' | grep "$filter"

取消grep

netstat -tulpn | awk -vq="$filter" -vOFS='\t' '$0!~q{next} /^tcp/{print $4,$7} /^udp/{print $4,$6}'

答案 1 :(得分:0)

另一个简单的解决方案

#!/bin/bash
[ "$1" ] && filter="^${1}"
sudo netstat -tulpn | grep -oP ':\K(\d+)(?=\s+)|\d+/.*$' | paste -d'\t' - - | grep "$filter"

如果你用第一个参数运行它,过滤器只搜索端口(从行的开头),没有第一个参数,它会显示所有信息。

grep搜索端口,将数据搜索到行尾,并在使用选项卡作为分隔符将两行合并到时间后,以便更好地清理输出。

一些例子

$ bash script
5939    863/teamviewerd     
631     25428/cupsd         
4505    950/python          
4506    956/python          
9050    704/tor             
631     25428/cupsd         
53835   539/avahi-daemon: r
5353    539/avahi-daemon: r 
68      20609/dhclient      
631     25430/cups-browsed  
5353    539/avahi-daemon: r 
38675   539/avahi-daemon: r 
$

$ bash script 6
631     25428/cupsd         
631     25428/cupsd         
68      20609/dhclient      
631     25430/cups-browsed  
$

$ bash script 63
631     25428/cupsd         
631     25428/cupsd         
631     25430/cups-browsed  
$