表达式在 for 循环中计算结果为 false,而在 if 中计算结果为 true

表达式在 for 循环中计算结果为 false,而在 if 中计算结果为 true

此命令输出在端口 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

相关内容