从一个bash脚本如何快速查找端口445是否在服务器上打开/监听。

我已经试过几个办法了,但我想快点: 1. lsof -i:445(需要数秒) 2. netstat -an |grep 445 |grep LISTEN(需要数秒) 3.Telnet(不返回) 4. 服务器上没有Nmap、netcat

知道一种不先枚举然后再grep的方法将会很好。


当前回答

我最近发现的一个惊喜是Bash原生支持tcp连接作为文件描述符。使用方法:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

我使用6作为文件描述符,因为0、1、2是stdin、stdout和stderr。Bash有时会将5用于子进程,因此3、4、6、7、8和9应该是安全的。

根据下面的注释,要在脚本中测试本地服务器上的侦听:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

要确定是否有人正在监听,请尝试通过环回连接。如果失败了,端口就会被关闭,或者我们不允许进入。然后,关闭连接。

根据您的用例修改它,例如发送电子邮件、在失败时退出脚本或启动所需的服务。

其他回答

你可以使用netcat。

nc ip port < /dev/null

连接到服务器,然后直接重新关闭连接。如果netcat不能连接,它将返回一个非零退出码。退出码存储在变量$?举个例子,

nc ip port < /dev/null; echo $?

当且仅当netcat成功连接到端口时返回0。

nc -l 8000

其中8000是端口号。如果端口是空闲的,它将启动一个可以轻松关闭的服务器。如果不是,它将抛出一个错误:

nc: Address already in use

tcp是一个开销非常低的好工具。它还有一个timeout参数,以使它更快:

[root@centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root@centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root@centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.

我最近发现的一个惊喜是Bash原生支持tcp连接作为文件描述符。使用方法:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

我使用6作为文件描述符,因为0、1、2是stdin、stdout和stderr。Bash有时会将5用于子进程,因此3、4、6、7、8和9应该是安全的。

根据下面的注释,要在脚本中测试本地服务器上的侦听:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

要确定是否有人正在监听,请尝试通过环回连接。如果失败了,端口就会被关闭,或者我们不允许进入。然后,关闭连接。

根据您的用例修改它,例如发送电子邮件、在失败时退出脚本或启动所需的服务。

你可以这样使用netstat来获得更快的结果:

在Linux上:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

在Mac:

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

这将输出在端口上侦听的进程列表(本例中为445),如果端口空闲,则不输出任何内容。