【发布时间】:2015-09-25 23:31:56
【问题描述】:
#!/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 运算符,它会“修复”问题(无论它是什么)。为什么?
【问题讨论】:
-
首先要调查的是你的 /bin/sh 是什么类型的 shell 和版本? - 然后调查该 shell 启动时运行的任何启动脚本。
-
...这就是说 - 正如我在您的另一个问题中所建议的那样,您是否考虑使用
set -x在运行时记录单个命令?我实际上可以想到一种可能的方式,您的脚本中的隐藏字符可能会导致这种行为,如果是这种情况,使用set -x会很清楚。 -
(从
-eq切换到=——因此,使比较基于字符串而不是数字——实际上会让你对我怀疑的故障模式更加稳健)。 -
...running
sh -x yourscript将,顺便说一下,与将set -x放在 shebang 下的行为相同;无论如何,您将获得所有运行命令的精确日志。 (尽管现在我想到了,对于一些较旧/功能较弱的外壳,这些外壳可能不会被转义以使隐藏的字符可见,从而降低了优势;在这种情况下,您可能需要使用od、hexdump,或类似的)。 -
有趣的是,
count=$((count + 1))在这里工作;我一开始会猜到你正在运行一个 pre-POSIX Bourne shell,但是那个扩展是在 POSIX sh 中添加的。