我正在开发一个高度可移植的脚本,用户应将其来源到他们的 shell,这迫使我使用 POSIX 脚本。
脚本中有许多有用的函数,其中之一很特殊,因为它返回
true
调用false
函数的状态。
return 0
现在,我曾经在这样的情况下使用过。但它似乎更具可读性true
或false
forreturn 1
也分别有效。
问题是它们的工作方式是否完全相同或者是否存在差异。谢谢。
我正在开发一个高度可移植的脚本,用户应将其来源到他们的 shell,这迫使我使用 POSIX 脚本。
脚本中有许多有用的函数,其中之一很特殊,因为它返回true
调用false
函数的状态。
return 0
现在,我曾经在这样的情况下使用过。但它似乎更具可读性true
或false
forreturn 1
也分别有效。
问题是它们的工作方式是否完全相同或者是否存在差异。谢谢。
true
是可移植的,但本身不会返回。return true
不便于携带,也不能可靠地工作。如果你有这样的函数:
那么是的,它将以退出状态为零的方式从函数返回。当从末尾掉下来时,返回最后一个命令的退出状态作为函数的退出状态。
但当然,这不会以真实状态返回,因为
true
中间本身不会影响控制流。但是您可以添加显式返回,因为
return
没有参数也使用最后一个命令的退出状态:现在,如果您尝试
return true
,它可能会在某些 shell 中执行您想要的操作,但最终可能不会。至少在 zsh 中,它似乎将参数视为算术表达式,因此return true
将使用变量的值true
,如果未设置,则默认为零。如果您可以安排将
true
始终设置为0
和false
并设置为1
,并且相信脚本库的用户不会弄乱这些,那么您可以在 zsh 或标准shell 中使用return true
和。我不建议使用这些名称,但也许可以使用类似或的名称。return false
return "$true"
return "$false"
true_return_value
false_return_value
否则,您可以在标准 shell 中使用
true; return
andfalse; return
,但我不确定这是否比return 0
and更具可读性return 1
。无论如何,shell 程序员都应该熟悉真实返回值为零这一事实。true
和false
不是可移植的有效布尔值。例如,一个简单的 shell 脚本
如果我们在不同的 shell 下运行:
(最后一个shell是pdksh 5.2.14)
不过
return 0
是便携的如果 0 被视为 true,我们还可以看到返回,因此有效
&&
。现在我们可以作弊了..
它的作用是调用
true
命令...,然后使用这样一个事实:没有显式的函数的返回码return
是最后一个命令运行的返回值。因此,虽然这可以工作,但它的可读性不高,因为没有明确的行为
return
,并且您依赖于隐式行为。以下是POSIX 对此的说法:
所以:
您可以使用
return
从源脚本(点脚本)返回,而不仅仅是函数。您可以传递 0 或 1 个参数(没有选项,
--
甚至可能不被接受),但这必须是无符号十进制整数(0
,1
,2
... 不是true
,0x1
,-1
,+1
, 不清楚,并且实际上不可移植,因为010
这可能是被视为八进制数,而不是十进制数,实际上就像在 sh 模拟中的 zsh 一样)因为
return
不带参数返回上一个命令的状态,{ true; return; }
所以可以是返回成功退出状态的一种方法。请注意,虽然这{ false; return; }
会以非退出状态返回,但未false
指定返回哪个退出状态(实际上,我从未见过任何使用除 之外的任何实现1
),并且如果选项false
可以退出 shell(或子 shell)errexit
已启用(可以使用 解决{ false || return; }
)。目前尚不清楚是否return $(true)
或return $(false)
应该起作用。实际上,它不在 dash 或 mksh 中,因此不可移植。目前尚不完全清楚shell 当前未执行函数或点脚本的确切含义。有些人将其解释为
return
从子 shell 中使用,即使该子 shell 是从函数或点脚本内运行,或者是函数体(如 中f() (return 1)
),也是未指定的。但在实践中,我发现return
在这些情况下,行为就像exit
. 它从当前子 shell 退出/返回,但不从封闭的函数/点脚本退出/返回。无论如何,要从函数/点脚本返回,如果该子 shell 不是函数/点脚本中的最后一个命令,则必须在子 shell 外部完成,请记住,子 shell 的构成因 shell 而异。例如在:
将从
return
ksh 或 zsh 中的函数返回,但不会在 bash(除非lastpipe
设置了该选项)或 dash、mksh 中返回,因为在这些中,所有管道组件,甚至是子 shell 中的最后一次运行(POSIX 允许)。所以你需要用类似的方法来解决它:强制使用子 shell 并
exit
在其中使用将使其明显符合 POSIX 并在 shell 之间保持一致的行为(并且更清楚的是$var
变量分配read
可能无法在管道中幸存):(在所有这些
return
/中exit
,将返回失败退出状态read
;您可以更改为exit 1
/return 1
以给出特定的失败退出状态值)! return
请注意或 的行为! return 1
是不可移植的(对于 没有那么有用,但如果可移植 for来从失败退出状态的循环中中断return
会更有用)。! break
在任何情况下,
true
和false
命令都不会导致封闭的函数/点脚本返回,除非已经注意到errexit
设置选项的特殊情况(并且其效果不会以某种方式取消),在这种情况下会失败包括导致 shell 进程退出的命令false
(不一定/仅包含封闭函数/点脚本),它们是普通命令,通常是内置的,但不是特殊的内置命令,更不用说与return
//break
...相反的控制流运算符了continue
为了使代码更清晰,您可以选择为成功退出状态和失败退出状态定义变量,例如:
并使用
return "$true"
orreturn "$false"
或 与 相同exit
,在 zsh 中可以简化为return $true
or 甚至return true
但请注意,在算术表达式中,含义是相反的,0 表示 false,其他值表示 true,就像在 C 中一样。因此,这些变量的值
while (( true ))
(在类似 Korn 的 shell 中)将无法按预期工作,因此您可能更愿意命名这些变量变量status_ok
,status_failure
而不是ok
/failure
。