此命令输出在端口 8083 上侦听的进程的 PID:
lsof -i4TCP:8083 -sTCP:LISTEN -t
当没有进程时,返回空字符串。该端口上没有进程正在运行,因此我正在检查该命令是否返回空字符串
if [[ -z $(lsof -i4TCP:8083 -sTCP:LISTEN -t) ]]; then
echo "waiting for startup"
else
echo "process is listening on port 8083"
fi
它像预期一样输出“等待启动”,但是当我这样做时:
for (( ; -z $(lsof -i4TCP:8083 -sTCP:LISTEN -t) ; )); do
echo "waiting for startup"
sleep 1
done
它不输出任何内容,但在评估时此条件为真,if
因此如果为真,则此循环应执行do...done
块并打印“处理”,但它不会并立即退出。为什么会发生这种情况?
答案1
[[ … ]]
评估一个条件表达式。在条件表达式中,-z
是一个运算符,它接受字符串作为参数,如果字符串为空则返回 true,否则返回 false。
在 中for ((…; …; …))
,双括号内的三个分号分隔部分中的每一个都是一个算术表达式。在算术表达式中,-
是求反或减法运算符。z
是对变量 的引用z
,如果未定义变量,则值为 0。因此,当 的输出lsof -i4TCP:8083 -sTCP:LISTEN -t
为空且未z
定义时,表达式的计算结果为 0,因此循环退出。当输出不为空时,很可能会导致算术表达式出现语法错误。您所写的内容在算术表达式中没有意义。
这种形式for
是为由算术确定的迭代而设计的,通常从某个初始值计数到某个最终值。您似乎想要一个 while 循环,因此编写一个 while 循环,并使用条件表达式。
while [[ -z $(lsof -i4TCP:8083 -sTCP:LISTEN -t) ]]; do
echo "waiting for startup"
sleep 1
done
也可以看看bash 中的括号、方括号和大括号。
答案2
你为什么使用for
循环而不是while
?
while [[ -z $(lsof -i4TCP:8083 -sTCP:LISTEN -t) ]]
do
echo "waiting for startup"
sleep 1
done