shell 解释BASH代码行,使RETVAL=$((RETVAL|$?))

uajslkp6  于 2023-03-13  发布在  Shell
关注(0)|答案(2)|浏览(323)

我想从shell脚本中找到BASH下面一行的一些解释。我通常熟悉所有的内置函数和$(())的用法。我对这一行中的位OR运算符比较的是什么有点困惑。

let RETVAL=$((RETVAL|$?))
rjzwgtxy

rjzwgtxy1#

double 圆括号内,表达式不作为命令计算,而是作为算术表达式计算。
因此,这不是管道运算符,而是 * 按位或 * 运算符。
在这种情况下,它将设置变量RETVAL中在上一条语句的结果中设置的任何位(包含在特殊变量$?中)。
这可能只是滥用了位或作为逻辑运算符,因为只有当RETVAL$?的前一个值都为零时,结果才会为零(通常解释为success / true),换句话说,在多个命令之后重复使用它,只有当它们都返回零时,才会得到零结果。

gudnpqoy

gudnpqoy2#

这通常意味着有人将几个不同操作的退出状态进行“或”运算,以得出组合的退出状态。
let是进入算术上下文的过时方式;(( ))$(( ))是现代的替代物;因此,下面的代码倾向于使用更现代的bash-only语法($(( ))既现代又可移植,但需要您负责确保它所计算的值没有意外的副作用,而(( ))是现代的但不可移植,let既不可移植也不现代)。
假设您希望始终运行函数foo1foo2foo3,并报告其中是否有任何函数失败:

main() {
  local retval=0 # local is the only non-POSIX thing in this example
  foo1 || : $(( retval |= $? ))
  foo2 || : $(( retval |= $? ))
  foo3 || : $(( retval |= $? ))
  return "$retval"
}

...将返回一个退出状态,确定foo 1、foo 2或foo 3中是否有 * 任何 * 失败;并且如果它们的退出状态用作位掩码,则将设置高位以指示发生了哪些故障模式。
使用||而不是;是为了明确表示左侧命令的退出状态为“checked”,因此set -eERR陷阱在它们为非零时不会触发。
使用小写的变量名是为了遵守https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html中指定的约定,全大写的变量名用于对POSIX指定的工具有意义的变量,而至少有一个小写字符的变量名保留给应用程序使用,并保证不会对POSIX指定的工具产生意外的副作用。(因为设置常规shell变量会覆盖任何同名的环境变量,所以相同的约定适用于这两种类型)。

相关问题