我正在一台机器上运行下面的 shell 脚本,c++ 应用程序服务器在端口 8080 上运行,并且在 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 脚本。
答案1
该程序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
答案2
bash 中最简单的方法。测试您的端口是否开放。
(echo >/dev/tcp/localhost/8080) &>/dev/null && echo "TCP port 8080 open" || echo "TCP port 8080 not open"
将端口替换为您正在测试的端口。
或者你可以使用 nc.
nc -vz 127.0.0.1 8080
返回:
连接127.0.0.1 8080端口[tcp/*]成功
答案3
详细阐述 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