答案1
程序失败的原因有多种。例如,grep
如果找不到所需的模式,或者无法打开指定的文件之一,则会失败。
目前,Unix 允许 1 个(无符号)字节值(返回码)从子进程传回其父进程(我忽略了有关哪个信号杀死了子进程、是否生成了核心等信息,这可能会得到更多信息)位回来)。
由于失败的方式有多种,因此有多个返回代码来编码这些不同的失败,并有一个返回代码来指示成功是有意义的。
由此可见,( 0
) 是表示成功的合理选择,其余 (1-255) 表示失败(以及失败的类型)。
完全有可能使用 17 表示成功,并使用 0 到 16 和 18 到 255 表示失败,但为了简单起见,选择 0 表示成功,选择 1 到 255 表示失败,因此有一个范围。同样简单的是使用 255 表示成功,使用 0 到 254 表示失败。然而,这将限制未来的更改以回传超过 8 位,并保持单个故障代码范围的简单性。
答案2
您正在将苹果与梨进行比较。它们的味道不同。 :-)
算术
一个算术 0
在 c 和 shell 中都表示 false [a] :
$ if ((0)); then echo true; else echo false; fi
false
或者,在更便携的测试中,但更复杂:
$ echo $(( 22 == 23 ))
0
[a] 实际上,正在写入的是一个 ASCII 字符 ( 0
)(在大多数系统中为 ASCII,但也可能是其他系统),其十进制字节值48
被透明地转换为0
(A c char
of value 0
) 的字节值。这个字节值是否0
意味着 false在c中
对于大多数 shell 来说都是如此,因为算术扩展实际上是 c 算术的直接副本。那里不应该存在任何差异。
退出状态
但实用程序的退出状态 ( $?
) 有所不同:
$ echo "$(( 22 == 23 )) $? -- $((22 == 22 )) $?"
0 0 -- 1 0
理论
对于造成这种情况的原因,我只能提出自己的看法。
在经典逻辑,以其预期的语义,真值为真(用 1 或维鲁姆 ⊤),以及不真实或错误(用 0 或福尔苏姆 ⊥)
命题逻辑真值表:我们将 true 值表示为 1,将 false 值表示为 0。
nothing/empty
那只是人类更接近的思维方式的编纂false
。
该描述得到用c语言编码
但是对于错误的退出状态只有一个值 ( 0
) 似乎太狭窄了,逻辑颠倒过来, ( 0
) 改为成功,为几种可能的错误原因留下更多代码。这就是它在 shell 中的使用方式。
答案3
true = 1 和 false = 0 的由来
如果您想知道为什么 true 为 1 而 false 为 0 的历史背景,那么我想指出布尔代数是由 George Bool 在 1847 年“发明”的。这远远早于第一台电子计算机。布尔代数发表于《逻辑的数学分析》。您可以阅读古腾堡项目的副本:http://www.gutenberg.org/files/36884/36884-pdf.pdf
我并没有声称已经详细阅读过它,但我已经浏览了足够多的内容,发现乔治·布尔本人使用 1 作为 true,使用 0 作为 false。
布尔对计算的影响
布尔的代数(“布尔代数”)在很大程度上被忽视,直到他死后很久才被人们拾起并用于计算。甚至在基于硅的计算机之前,布尔代数就在二进制电子学方面变得有用(而不是模拟)。将数学逻辑运算符转变成晶体管接线很简单(请参阅这里)。从那里开始,将多个逻辑门连接在一起以表示二进制数和进行简单的算术运算。
关于“if”语句,这些语句源自 CPU 的“条件跳转”操作,其中跳转goto
在高级语言中称为跳转。
对于条件跳转,CPU 必须定义一种有用的方法来选择跳转或不跳转。两个最常见的条件是“如果为零则跳转”和“如果为负则跳转”(参见第 39 页带下划线的这里)。然而,将数字解释为正数或负数可能是主观的,因为相同的 CPU 操作用于两人的赞美有符号整数作为“无符号”整数。
所以这就是说,常见的if
说法将 0 表示为假,1 表示为真,因为:
- 负/正定义不适用于无符号整数
- 0 代表真,1 代表假,这与常用的布尔代数相反
为什么外壳不一样?
外壳做相反事情的起源很难找到。 0 的成功肯定可以追溯到 20 世纪 70 年代可能是unix的最早版本(没有把握)。
我自己的看法是,一个项目只能以一种方式完全成功,但在很多方面都会失败。
看起来很清楚的是true
andfalse
命令的设计是为了符合 shell 对在条件逻辑中使用命令的退出状态的解释:
if first_command ; then
second_command
fi
如果上面的代码的意思是second_command
如果first_command
成功就运行。那么对于总是成功的逻辑占位符来说,一个好名字就是true
。
答案4
我只能想到这个理由,而且对我来说似乎相当有力。
将布尔运算转换为计算机算术的最简单方法是使用0
forFALSE
和1
for TRUE
,然后使用它们进行的所有运算都有意义,即
TRUE && TRUE = TRUE ( 1 * 1 = 1)
TRUE && FALSE = FALSE ( 1 * 0 = 0)
TRUE || FALSE = TRUE ( 1 + 0 = 1)
FALSE || FALSE = FALSE ( 0 + 0 = 0)
等等等等。
同时程序需要多种退出状态来报告各种错误。将正确的退出状态设置为0
,然后使用剩余的 255 (无符号字符)作为错误的退出状态是合乎逻辑的。
当然,现在本来1
可以取得良好的退出状态,但随后糟糕的退出状态就会变成一堆撕裂的阵列0
,2..555
这是非常不合逻辑的。