我的外壳坏了吗? [英] Is my shell broken?
问题描述
#!/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"
您希望上面的脚本输出以下内容,对吧?
You'd expect the script above to output the following, right?
foo is 0
inside while: foo is 0
after while
它可以在许多其他计算机上运行,例如您自己的计算机.但是不是我的...
And it does on many other machines, like your own. But not mine ...
foo is 0
inside while: foo is 0
inside while: foo is 1
inside while: foo is 1
... (infinite loop)
我做错了什么,还是我错过了明显的事情?
Am I doing something wrong, or am I missing something obvious?
在这台(损坏的?)计算机上,如果我调整while
条件以使用过时的" -a
运算符,它将解决"该问题(无论它是什么).为什么?
On this (broken?) machine, if I tweak the while
conditional to use the "obsolescent" -a
operator, it "fixes" the problem (whatever it is). Why?
推荐答案
假设脚本文本中没有隐藏的字符(假设我建议您花些力气进行验证!),这确实表现出与POSIX sh标准相反的行为
Assuming no hidden characters in your script text (an assumption I would suggest putting some effort into verifying!), this is indeed exhibiting behavior contrary to the POSIX sh standard.
n1 -eq n2
-如果整数n1和n2代数相等,则为true;否则为true.否则为假.
n1 -eq n2
- True if the integers n1 and n2 are algebraically equal; otherwise, false.
值得注意的是,如果任何一个参数实际上都不是整数,则这不会给出任何说明或保证.例如,如果它将是一个整数,但末尾有回车符或其他非打印字符.
Notably, this makes no specifications or guarantees about what happens if either argument is not in fact an integer; for instance, if it would be an integer, but has a carriage return or other nonprinting character on the end.
按顺序尝试其他项目:
- 运行
sh -x yourscript
,并在运行循环时查看调用test
的确切参数.还要确定&&
链中的第二个测试是否完全运行. - 将运算符从
-eq
更改为=
,运行字符串比较而不是数字比较(从而确保任何包含隐藏字符的字符串都无法与字符串0
成功比较,而不是依靠这种情况下的行为未定义). - 用
false
替换[ "$foo" -eq 0 ]
,并确保循环中的内容不运行(因此,请仔细检查shell实现的其他一些核心部分).
- Run
sh -x yourscript
, and look at the exact arguments called totest
when running the loop. Also determine whether the second test in the&&
chain is run at all. - Change your operator from
-eq
to=
, running a string comparison rather than a numeric comparison (and thereby ensuring that any string containing hidden characters will fail to compare successfully with the string0
, rather than relying on undefined behavior in this case). - Replace
[ "$foo" -eq 0 ]
withfalse
, and ensure that the contents of the loop do not run (thus sanity-checking some other core parts of the shell's implementation).
这篇关于我的外壳坏了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!