特殊的 Solaris 整数比较行为

特殊的 Solaris 整数比较行为

这让我措手不及!

我们有一台 Solaris 机器(版本:SunOS 5.8),托管一个关键脚本/进程,该脚本/进程已经运行了很多年,没有任何投诉。我们最近有理由深入了解一下,发现一个测试条件——据我所知——不应该起作用,但由于某种原因可以:

$ sh
$ [ 90% -gt 95 ]; echo $?
1
$ [ 96% -gt 95 ]; echo $?
0

什么?!这看起来并不是侥幸:

$ [ 96% -lt 95 ]; echo $?
1
$ [ 96% -eq 96 ]; echo $?
0   

这不仅仅是以下%两者之一:

$ [ 96blah -eq 96 ]; echo $?
0
$ [ 1.2 -gt 1 ]; echo $?
1

在 SunOS 5.8、5.9 和 5.10 上似乎是这样,但我以前没有注意到这一点。不幸的是,我手边似乎没有另一个非 Solaris 系统可以轻松地检查它是否没有/bin/sh符号链接到 bash(它的解释不太自由)。

那么,除了草率的代码(x%通过变量传递并且可能没有被注意到)之外,为什么标准(大概是 Bourne?)shell 通过截断这些测试参数将它们视为整数?这是有记录的行为吗?我看不到任何东西,man sh但可能错过了一些东西。

注意:这实际上是另一个奇怪的测试条件下的次要嘘声,但这可能值得它自己的问题。

答案1

由于我无法将注释格式化为预期的行,因此我使用答案表单来解释有关如何获取 POSIX shell 的注释。

获取 POSIX shell 的官方方法是:

1)  unset PATH                       # if you run an older Bourne Shell
2a) PATH=`getconf PATH`              # this is with the Bourne Shell
2b) PATH=$(command -p getconf PATH)  # this is with a Korn shell
3)  sh                               # This starts a POSIX shell

已经进行了多次标准化尝试#!/path/to/shell,但 POSIX 不处理 PATH,因此我们找不到解决方案。

答案2

看起来这个问题已经在评论中得到了回答:Solarissh有一些怪癖。至少在过去,它甚至不是 POSIX shell。 (Schily 指出 POSIX 不需要/bin/sh是 POSIX sh,这意味着您必须跳过另一个环节才能编写完全可移植的 shell 脚本。)

这个问题可能有一些有用的信息/链接:https://superuser.com/questions/125728/what-is-the-difference- Between-bash-and-sh

Schily 的回答指出,该标准没有指定尾随垃圾的数字会发生什么,因此您的脚本实际上具有未定义的行为,并且依赖于 Solaris 的行为sh。因此,它不可移植。

bash类似的事情是显然不建议在/bin/shSolaris 系统上使用它的主要原因。一些 GNU/Linux 发行版使用dashfor /bin/sh,而其他发行版则使用bash.

我在我安装的 3 个 shell 上测试了你的代码:

bash  4.3-11ubuntu2
$ [ 96blah -eq 96 ]; echo $?
bash: [: 96blah: integer expression expected
2

dash  0.5.7-4ubuntu1
$ [ 96blah -eq 96 ]; echo $?
dash: 1: [: Illegal number: 96blah
2

busybox sh  1.22.0-9ubuntu1
$ [ 96blah -eq 96 ]; echo $?
sh: 96blah: bad number
2

答案3

该标准规定测试运算符喜欢-gt将其操作数作为整数进行比较,但它没有提到当提供的字符串不是整数时会发生什么。所以观察到的行为是完全正确的。顺便说一句:它也与历史 UNIX 行为兼容。

/bin/sh 当然没有链接到 bash,因为 bash 不够符合标准,可能会导致很多脚本失败。

2010 年,随着 Solaris 10 的发展,/bin/sh 被 ksh93 取代,尽管 ksh 比 bash 更兼容 Bourne Shell,但这导致 Solaris 无法在不同的文件系统中拥有 / 和 /usr之前没有问题。请注意,ksh93 从 /usr 加载动态库。

相关内容