为什么 bc 除以 0 时退出 0?

mbi*_*ras 3 command-line posix bc

我试图想出一种快速且说明性的方法来生成不成功的退出状态,并认为除以零与bc将是一个好主意。

我惊讶地发现,虽然它确实产生了运行时错误,但退出状态仍然是 0:

$ echo 41 + 1 | bc
42
$ echo $?
0
$ echo 42/0 | bc
Runtime error (func=(main), adr=6): Divide by zero
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
  • 为什么 bc 实用程序不会以非零退出状态失败?

注意:对于我正在使用的快速非零退出状态 return 1

另外,来自shell-tips

$ expr 1 / 0
expr: division by zero
$ echo $?
2
Run Code Online (Sandbox Code Playgroud)

Wil*_*ard 6

查看规范;这是预期的行为。

所有输入都被 正确读取bc,因此它产生退出状态 0。

如果你bc在一个不存在的文件上运行,比如bc nosuchfile,你会得到一些其他的退出状态。


为了说明非零退出状态,我将比较ls somefilels nosuchfile,或者我将展示退出状态 1 和 2 的常规使用方式(1 表示预期错误或失败状态,2 表示意外错误),如下所示:

$ echo hello > file1
$ echo hello > file2
$ echo goodbye > file3
$ cmp -s file1 file2
$ echo $?
0
$ cmp -s file1 file3
$ echo $?
1
$ cmp -s file1 file4
$ echo $?
2
$ 
Run Code Online (Sandbox Code Playgroud)

  • 这是 _accepted_ 行为,但不是 _mandated_ 也不是推荐的(所以我不会把 _expected_ 放在这里)。如果有错误,退出状态是未指定的。在这里,无论 POSIX 一致性如何,在 GNU bc 的情况下,我认为这是一个错误,因为除以零(但也有语法错误),这是一个致命错误,`bc` 不处理进一步的输入。 (2认同)

Gil*_*il' 6

bc实现的返回状态略有不同,但总体思路是,如果您提供有效输入,bc则以状态 0 退出。42/0是有效输入:没有读取错误,它甚至是语法上有效的表达式,因此bc返回 0。如果您通过另一个操作的第二行,bc将执行它。这不同于expr其目的是评估单个算术表达式;在这里,单个表达式的结果决定了返回状态。

生成指示失败的退出状态的最直接方法是调用false. 诸如此类的东西expr 1 / 0只在混淆的编程竞赛中占有一席之地。