使用 $# 和 $ 在语法上是否正确/良好的做法?在算术测试条件下?

使用 $# 和 $ 在语法上是否正确/良好的做法?在算术测试条件下?

我看过很多帖子使用

if [ $? -ne 0 ]; then  
  return
fi

if [ $? -eq 0 ]; then
  eval "set -- ${opts}"
  while [ $# -gt 0 ]; do
    case $1 in

用于检查“最后退出状态”和“位置参数数量”的值。

不过,我一直在使用$#and$?如下,没有明显问题:

if (( $? != 0 )); then
 ...

或者

if (( $? == 0 )); then
  ...

那么,这些方法中的一种是不好的做法还是语法规则的“延伸”,而另一种是使用这些变量的“正确”方法?或者可以安全地使用这两种风格吗?

答案1

是的,$?(and $#) 是一个数值,您可以使用算术比较结构。但请注意,使用(( ... ))as 测试构造是 Bash 特定的,以这种方式编写的脚本可能不可移植 - 这与算术$(( ... ))不同扩张这是一个POSIX 标准功能

我之所以使用[ $? -eq ... ](或 Bash 特定的[[ ... ]]) 测试结构进行检查$?,是因为在算术上下文中是不必要的,因此通常从变量引用中省略,但在(和)$的情况下这是不可能的。$?$#

的数值范围$?为 0 到 255 (1)(2)。虽然原则上您可以编写一个返回 的 shell 脚本exit -2,但$?执行后调用将(通常)显示 254 (但请注意,并非所有 shell 都允许这样做 - 有些会说sh: 1: exit: Illegal number: -2相反)。


(1) 正如 @glenn jackman 在评论中所解释的,退出状态是作为unsigned char变量实现的,因此只能保证容纳 0 到 255 之间的整数。

(2) 此外,正如 @Paul_Pedant 在评论中指出的那样,虽然可执行文件的程序员可以选择 0-255 范围内的任何值作为退出代码,但 0 通常用于指示成功完成,并且 shell 可以使用高于 125 的值一种特殊的方式,如上所述这里例如,因此在这种情况下,确切的值可能不可靠或至少难以正确解释。

答案2

是的,$?最后一个进程的状态是一个数值,范围是 0 到 255。

但是,对数值使用字符串比较运算符==and是不明智的。!=使用-eqand-ne代替。读man bash

相关内容