过滤 netstat 输出以获取 bash 中的特定端口
Filter netstat output to get specific ports in bash
我正在使用命令 sudo netstat -tulpn
获取计算机上所有打开端口的列表 运行 Ubuntu 服务器 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/Program 名称
基本上,我想要这种行为:
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"
这个脚本接近于我想要做的,但是它打印了 State 列,这是我不想要的(因为最后几行缺少一些信息)和它还以相当粗糙的状态打印数据。
我正在考虑为此使用 awk
,但我无法正确使用它来实现此目的。
由于netstat
的列宽是固定的,最简单的解决办法就是使用cut -cN-M
,例如:
#/bin/bash
filter=${1:-""}
netstat -tulpn | cut -c21-44,81- | grep "$filter"
另一种方法是将 tcp
从 udp
拆分出来,并为每个使用不同的列号。使用 awk
,您可以这样做:
netstat -tulpn | awk -vOFS='\t' '/^tcp/{print ,} /^udp/{print ,}' | grep "$filter"
消除grep
:
netstat -tulpn | awk -vq="$filter" -vOFS='\t' '[=12=]!~q{next} /^tcp/{print ,} /^udp/{print ,}'
另一个简单的解决方案
#!/bin/bash
[ "" ] && filter="^"
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
$
我正在使用命令 sudo netstat -tulpn
获取计算机上所有打开端口的列表 运行 Ubuntu 服务器 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/Program 名称
基本上,我想要这种行为:
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"
这个脚本接近于我想要做的,但是它打印了 State 列,这是我不想要的(因为最后几行缺少一些信息)和它还以相当粗糙的状态打印数据。
我正在考虑为此使用 awk
,但我无法正确使用它来实现此目的。
由于netstat
的列宽是固定的,最简单的解决办法就是使用cut -cN-M
,例如:
#/bin/bash
filter=${1:-""}
netstat -tulpn | cut -c21-44,81- | grep "$filter"
另一种方法是将 tcp
从 udp
拆分出来,并为每个使用不同的列号。使用 awk
,您可以这样做:
netstat -tulpn | awk -vOFS='\t' '/^tcp/{print ,} /^udp/{print ,}' | grep "$filter"
消除grep
:
netstat -tulpn | awk -vq="$filter" -vOFS='\t' '[=12=]!~q{next} /^tcp/{print ,} /^udp/{print ,}'
另一个简单的解决方案
#!/bin/bash
[ "" ] && filter="^"
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
$