如何通过Shell脚本检查特定端口是否在计算机上打开并基于该端口执行操作?


24

我在端口8080上运行c ++应用程序服务器的计算机上运行下面的Shell脚本,并且在Shell脚本中,我正在执行URL并将来自该URL的响应存储在DATA变量中。

但是,假设同一台应用服务器已关闭,则它将无法执行该URL,然后将其打印Retrying Again并休眠30秒,然后再次执行相同的URL。

#!/bin/bash

HOSTNAME=$hostname
DATA=""
RETRY=15

echo $HOSTNAME

while [ $RETRY -gt 0 ]
do
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    if [ $? -eq 0 ]
    then
        break
    else
        echo "Retrying Again" >&2

        # restart the server

        let RETRY-=1
        sleep 30
    fi
done

echo "Server is UP"

HOSTNAME是我在上面运行shell脚本的服务器的本地主机名。

问题陈述:-

现在我想做的是,如果服务器关闭,它将打印出来,Retrying Again因此之后我要检查端口8080是否打开$HOSTNAME。如果不是,则表示服务器已关闭,因此我想通过执行此命令来重新启动服务器,然后休眠30秒,如上面的Shell脚本所示。

/opt/app/test/start_stop.sh start

我上面的shell脚本可以在这里做吗?

我在Ubuntu 12.04上运行此Shell脚本。

Answers:


23

该程序lsof允许您检查哪些进程正在使用哪些资源,例如文件或端口。

要显示哪些进程正在侦听端口8080:

lsof -Pi :8080 -sTCP:LISTEN

在您的情况下,您想测试某个进程是否正在侦听8080-此命令的返回值告诉您。它还会打印过程的pid。

lsof -Pi :8080 -sTCP:LISTEN -t

如果只需要测试而没有输出,请将其重定向到/dev/null

if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; then
    echo "running"
else
    echo "not running"
fi


如果您在本地使用具有多个IP地址的多个主机名,请也指定主机名,例如
lsof -Pi @someLocalName:8080 -sTCP:LISTEN


谢谢沃尔克。我试过了lsof -i :8080 -sTCP:LISTEN,但控制台上什么也没得到,但是如果我试了一下,netstat -tulpn | grep :8080那么我得到的进程正在端口8080上运行,为什么会这样呢?
2014年

输出是netstat -tulpn | grep :8080什么?
Volker Siegel 2014年

这就是我用netstat所得到的 david@machineA:/home/david$ netstat -tulpn | grep :8080 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 27530/test_server
大卫

奇怪的是,如果我尝试类似的方法,它会起作用。可能与IPv6相关...嗯。
Volker Siegel 2014年

列出了lsof -iTCP -sTCP:LISTEN | grep 8080吗?
Volker Siegel 2014年

16

bash中最简单的方法。测试您的端口是否打开。

(echo >/dev/tcp/localhost/8080) &>/dev/null && echo "TCP port 8080 open" || echo "TCP port 8080 close"

将回声替换为所需的内容。

或者您可以使用nc。

nc -vz 127.0.0.1 8080

返回值:

连接到127.0.0.1 8080端口[tcp / *]成功


1
nc对于我的用例来说是一个很好的解决方案;感谢您的建议
Jon

1

详细说明RJ的答案,哪些注释nc也很有用...不仅nc对快速命令行查询有用

 nc -z -v -w5 127.0.0.1 8080
localhost [127.0.0.1] 8080 (http-alt) : Connection refused

但是,如果不是您想要的可读性,则可以不使用-v来使用它-例如,用于脚本中(退出代码将指示端口是打开还是关闭)。

 nc -z 127.0.0.1 8080

 echo $?             
1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.