#!/bin/sh
count=0
foo=0
echo "foo is $foo"
while [ "$foo" -eq 0 ] && [ "$count" -lt 10 ]; do
echo "inside while: foo is $foo"
count=$((count+1))
foo=1
done
echo "after while"
您希望上面的脚本输出以下内容,对吧?
foo is 0
inside while: foo is 0
after while
它可以在许多其他机器上运行,就像你自己的机器一样。但不是我的......
foo is 0
inside while: foo is 0
inside while: foo is 1
inside while: foo is 1
... (infinite loop)
我做错了什么,或者我错过了一些明显的东西?
在这台(损坏?)机器上,如果我调整while
条件以使用"过时" -a
运算符,它"修复"问题(无论是什么)。为什么呢?
答案 0 :(得分:1)
假设您的脚本文本中没有隐藏的字符(假设我建议您进行一些验证!),这确实表现出违反POSIX sh标准的行为。
n1 -eq n2
- 如果整数n1和n2在代数上相等则为真;否则,错误。
值得注意的是,如果任何一个参数实际上不是一个整数,那么就没有规定或保证会发生什么。例如,如果它将一个整数,但在末尾有一个回车符或其他非打印字符。
要按顺序尝试的其他项目:
sh -x yourscript
,查看运行循环时调用test
的确切参数。同时确定&&
链中的第二个测试是否完全运行。-eq
更改为=
,运行字符串比较而不是数字比较(从而确保包含隐藏字符的任何字符串都无法与字符串{{1}成功比较在这种情况下,而不是依赖于未定义的行为。)0
替换为[ "$foo" -eq 0 ]
,并确保循环的内容不会运行(从而对shell的其他核心部分进行完整性检查)。