我需要编写一个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中的范围搞砸了。)
答案 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万岁: - )