我想使用bash命令来查找是否有进程正在监听80端口,但现在我遇到了其他的端口号,这让我很烦恼。我该如何在grep中过滤掉这些端口号?
netstat -ant|grep LISTEN|grep 80|wc -l
它还输出其他记录,如8080、8088等。
我正在查看我的netstat
命令的输出,并看到以下内容:
tcp4 0 0 10.0.1.10.56941 64.34.119.101.80 ESTABLISHED
tcp4 0 0 10.0.1.10.56936 64.34.119.101.80 ESTABLISHED
tcp4 0 0 10.0.1.10.56932 64.34.119.101.80 ESTABLISHED
tcp4 0 0 10.0.1.10.56929 64.34.119.101.80 ESTABLISHED
tcp4 0 0 10.0.1.10.56922 64.34.119.101.80 ESTABLISHED
tcp4 0 0 10.0.1.10.56914 64.34.119.101.80 ESTABLISHED
tcp4 0 0 *.* *.* CLOSED
tcp46 0 0 *.80 *.* LISTEN
tcp4 0 0 127.0.0.1.49153 *.* LISTEN
tcp4 0 0 127.0.0.1.49152 *.* LISTEN
tcp4 0 0 *.631 *.* LISTEN
tcp6 0 0 *.631 *.* LISTEN
grep "\.80 "
这段文字与it技术有关,将只选取端口80。 \。
表示选取句号。(一般在正则表达式中,“.”代表任何字符)。并且,在 80
后面加一个空格,可以保证你不会选择到端口8080。实际上,你可以保证不会选择包含 .80
的IP地址。
事实上,我建议使用 awk
而不是 grep
。使用 awk
,您可以指定字段并进行更多的处理:
$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /\.80$/' | wc -l
awk
命令时,每个列自动变成一个单独的字段。第6个字段(在 awk 中为 $6)是包含 ESTABLISHED
、CLOSED
、LISTEN
等内容的字段。字段 $4
是第一列 IP 地址。
在上述示例中,我正在查找第六个字段中包含单词 LISTEN 的行,并且第四个字段与正则表达式 \.80$
匹配。 $
是字符串末尾的锚点,\.
代表匹配小数点而不是任意字符。 awk
命令会自动打印出每个匹配的行,因此无需指定。
awk 实际上是一种编程语言。它假设对文件的每一行进行读取循环。您可以有一个在文件读取之前执行的 BEGIN
子句和一个在文件读取后执行的 END
子句。各个字段都被编号并用美元符号表示。特殊变量 $0
表示整行。像 NF 这样的特殊变量可提供行中字段的数量,NR 可提供已读取行数。您还有一系列函数可帮助解析文本等操作。以下是一个完整的 awk
脚本版本,基本上为您列出了所有内容,并进行了自己的行计数,因此无需使用管道传输到 wc -l
命令:
$ netstat -ant | awk '
BEGIN {total = 0}
END {print "There are " total " lines I found"}
{
if ($6 == "LISTEN" && $4 ~ /\.80$/) {
total = total + 1
}
}'
OP获得以下输出:
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /:80$/' | wc -l
将\.
替换为:
或其他特定于您的数据库的字符,例如_
。
$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /[\.:]80$/' | wc -l
这里使用了[\.:]
, 无论是冒号还是句号都可以匹配。好吧,干脆把所有的情况都考虑进去吧...
$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /[^0-9]80$/' | wc -l
< p > [^0-9]
的意思是不是数字字符。这样做没错。这样,无论是句号、冒号、分号、逗号还是你使用的netstat
的任何分隔符,它都可以工作。
不要使用netstat
命令并过滤掉大部分无用信息,而是直接使用fuser
命令来查询你关心的端口所属的进程:
$ fuser -n tcp 4005
4005/tcp: 19339
如果你只关心是否有任何进程打开了指定端口,你可以更快、更高效地完成操作,而无需处理输出结果,只需使用 fuser 命令的 -q
参数,并针对其退出状态进行操作:
if fuser -q -n tcp 4005 ; then
echo "port is in use"
else
echo "port not in use"
fi
fuser -n tcp ,,80
...或连接到特定主机上的远程端口:
fuser -n tcp ,1.2.3.4,80
简而言之,使用正确的工具直接查询所需参数可以避免首先需要进行基于文本的过滤。
Use grep ":80 "
instead of grep 80
:80
)。然后,最快的方法就是这样:netstat -ant | grep ':80\b.*LISTEN'
这样你就不会两次调用 grep
了。此外,grep
还有计算匹配数量的能力,可以使用 -c
代替 wc
:
netstat -ant | grep -c ':80\b.*LISTEN'
netstat -ntpl | grep ':PORT '
示例:$ netstat -ntpl | grep ':80 '
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12960/nginx -g daem
tcp6 0 0 :::80 :::* LISTEN 12960/nginx -g daem
netstat -ant |egrep "^tcp +[[:digit:]]+ +[[:digit:]]+ +[[:digit:]\.]+\:80 +.*LISTEN *$"
netstat
输出的是句号而不是冒号。只需将命令更改为$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /:80$/' | wc -l
。那应该就能解决问题了。如果你这样做:$ netstat -ant | awk '$6 == "LISTEN" && $4 ~ /[\.:]80$/' | wc -l
,无论netstat
使用冒号还是句号,都可以得到结果。实际上,请参见我的答案附录。 - David W.