bash子命令的评估时间

时间:2015-06-23 18:52:02

标签: bash

我需要编写一个bash脚本来完成某项任务,并发现这段代码导致无限循环:

echo "Waiting for job to complete"
until [ "$(curl "$url" -u $CREDENTIALS 2>/dev/null)" == "Idle" ]; do
    echo -n "."
    sleep 30
done

即使我的curl命令的结果等于"Idle",循环仍然继续,显然在每次比较中使用curl命令的旧结果。

curl命令解压缩到临时变量可修复此问题。

什么时候bash扩展$?还有什么其他的“问题”我应该注意什么?

修改

根据我的例子的具体平台,我以跨平台的方式再现了这个例子:

#!/bin/bash
# This will result in an infinite loop, and I don't know why

i=0
mocked() {
    i=$(($i+1))
    if [ $i -lt 5 ]; then
        echo "Non-Idle"
    else
        echo "Idle"
    fi
}

until [ "$(mocked)" == "Idle" ]; do
    echo -n "."
done

mocked中的条件更改为if false会导致until循环永不运行,因此我确定存在某种缓存问题。

编辑2

所有实验表明,这是一种在正常情况下从未发生过的怪异事故,而不是bash的限制。无论如何,我将curl命令保存在临时变量中。 (问题的第二次复制是巧合,bash中的范围搞砸了。)

1 个答案:

答案 0 :(得分:3)

每次评估条件时(即每次循环迭代)都会执行命令替换。

看起来还有其他事情正在发生,我们无法确定,因为您没有告诉我们$url包含的内容。简而言之,curl命令的输出从不 Idle。如果你给我们的结果

,我们可以说更多
 printf '<%s>' $(curl "$url" -u $CREDENTIALS)

例如,这个小片段就像预期的那样在bash中工作。当当前时间的秒部分达到42时停止:

 set -x ; until [ $(date +%S) = 42 ]; do echo -n .; sleep 0.5; done

PS:应该使用=运算符来测试字符串相等性。 ==是为无知者发明的非便携式基础。在其他炮弹中,可能无法识别。请尽快忘掉它。 POSIX万岁: - )