SC2155的最佳实践:单独声明和分配

SC2155的最佳实践:单独声明和分配

我正在编写 bash 脚本,而我的 IDE 抱怨以下声明:

local grey=$(tput setaf 154)
local red=$(tput setaf 196)
local bold=$(tput bold)
local default=$(tput sgr0)

它是这么说的:

Declare and assign separately to avoid masking return values.
See SC2155.

我理解这个警告的含义,并且我能够摆脱这个警告,但我的最终代码看起来很丑陋。

我可以这样抑制警告:

# shellcheck disable=SC2155
local grey=$(tput setaf 154)

# shellcheck disable=SC2155
local red=$(tput setaf 196)

# shellcheck disable=SC2155
local bold=$(tput bold)

# shellcheck disable=SC2155
local default=$(tput sgr0)

或者我可以这样分开声明和赋值:

local grey
grey=$(tput setaf 154)

local red
red=$(tput setaf 196)

local bold
bold=$(tput bold)

local default
default=$(tput sgr0)

上面的解决方案太冗长了。

我也可以这样做:

local grey; grey=$(tput setaf 154)
local red; red=$(tput setaf 196)
local bold; bold=$(tput bold)
local default; default=$(tput sgr0)

但我不确定正确解决该问题的最佳方法是什么。也许我可以忽略这个警告,因为我的表情很好。不确定编写符合标准的干净 bash 脚本的最佳方法是什么。

答案1

我认为“最佳实践”没有单一的答案。我会写的方式是

local grey red bold default
grey=$(tput setaf 154)
red=$(tput setaf 196)
bold=$(tput bold)
default=$(tput sgr0)

不将类似声明与涉及命令替换的赋值结合起来的原因local是, 的状态var=$(somecommand)是 的退出代码somecommand,但 的状态local …始终为 0。因此local var=$(somecommand)隐藏了 的任何错误somecommand。出于同样的原因,您不应在同一分配中放置多个命令替换。

$?当然,只有当您通过检查或打开来真正关注命令的状态时,这才有意义set -e

您可能会选择随意使用不太可能失败的命令,例如destination_file=$(dirname -- "$other_file")/$(basename -- "$source_file")tput不是其中之一:如果脚本在缺少所请求功能的终端上运行,它将失败。

不将声明与赋值结合起来的另一个原因是它仅适用于标量,不适用于数组。将声明与文字字符串或数字 ( local filename='hello.txt', local -i n=3) 组合起来就可以了。

答案2

另一种可能性是提供-r(只读)选项local

local -r grey=$(tput setaf 154)
local -r red=$(tput setaf 196)
local -r bold=$(tput bold)
local -r default=$(tput sgr0)

Shellcheck 不会抱怨这一点,因为只读变量必须在声明时分配。当然,这并没有解决 SC2155 的根本原因,即返回值仍然被吞噬,因此它可能不能被称为“最佳实践”。但如果你无论如何都要忽略返回值,那也没关系。

相关内容