我正在编写 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 的根本原因,即返回值仍然被吞噬,因此它可能不能被称为“最佳实践”。但如果你无论如何都要忽略返回值,那也没关系。