有一种病叫做代码编写规范强迫症,不知道规范都不知道怎么开始写代码,必须先看一遍代码编写规范!

背景

之前看过 Google 的关于 Shell 脚本编写规范的内容,里面提到:

使用 local 声明特定功能的变量。声明和赋值应该在不同行。

当赋值的值由命令替换提供时,声明和赋值必须分开。因为内建的 local 不会从命令替换中传递退出码。

踩坑

遵循规范

自打那之后,每当我使用 local 定义变量时,我都会这样写:

local image_id
image_id=$(docker images | grep my_container)

出现问题

没问题,上面的写法确实规范。但是,当 shell 脚本中使用 set -e 时,如果 grep 没有匹配到内容的话,整个脚本就会在变量赋值的时候退出。

grep 没有匹配到内容时,退出码是 1。

$ grep -vE '^[.]' <<<$'.\n.'; echo $?
1

避坑

方式一

grep 前使用 set +e,grep 结束之后再使用 set -e

local image_id

set +e
image_id=$(docker images | grep my_container)
set -e

方式二

local image_id
image_id=$(docker images | grep my_container) || true

方式三

同时进行声明和赋值,巧妙利用 内建的 local 不会从命令替换中传递退出码

local image_id=$(docker images | grep my_container)