我的外壳坏了吗? [英] Is my shell broken?

查看:101
本文介绍了我的外壳坏了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#!/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 to test 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 string 0, rather than relying on undefined behavior in this case).
  • Replace [ "$foo" -eq 0 ] with false, and ensure that the contents of the loop do not run (thus sanity-checking some other core parts of the shell's implementation).

这篇关于我的外壳坏了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆