当前位置: 首页 > 工具软件 > ShellCheck > 使用案例 >

shellcheck 常用错误

陶宏浚
2023-12-01

shellcheck 常用错误

linux环境下使用命令,可以查看shell脚本的语法错误,以及shellcheck给出的建议。

shellcheck  脚本

在信息的最后几行,shellcheck给出了解决错误的网址,如:

For more information:
http://www.shellcheck.net/wiki/sc2181 – Check exit code directly with e.g…

登录这个网址就可以查看错误的具体原因和解决建议。 shellcheck检查出来的错误有两种:1、语法错误,比如赋值的时候=两侧有空格,这类错误很容易修改。2、语法不规范,这类错误不是一定会引发问题,而是在某些场景下可能会出问题,如果坚信自己的脚本应用场景非常简单,不会出现此类情况,可以使用disable屏蔽。 以下记录今天遇到的几个错误,就属于第二种情况:

sc2164

我的源代码类似:

  cd  foo
 function()
 cd   -

  shellcheck认为这是有问题的,根本原因是,cd命令可能 因为各种原因失败,比如拼写错误,缺少路径,缺少权限以及软连接失效等等;当出现这些情况,而脚本继续执行的话,那么所有的操作都是在错误的路径下执行的,想想如果function()在错误的路径下执行了一些删除文件的操作,想想都头大。
  解决建议:

  • cd foo || exit
    ||代表或,cd foo执行成功了就不会执行exit,如果cd foo失败则执行exit。
  • cd foo || { echo "Failure"; exit 1;}
    这种比第一种更好一点,会打印信息和错误码
  • if cd foo; then echo "Ok"; else echo "Fail"; fi
    这种比第二种又更进一步,执行成功或者失败都有打印。
    -cd foo && function()
    &&是且的关系,cd foo成功了,才执行function(),失败了不执行function()

sc2086

使用双引号“”保持你想要的变量内容是一个整体。
在使用变量的时候,最好用“”把它引起来,如果不用“”,变量内容中有空格,会造成出乎意料的结果。
案例一:

name="little dog"
[ $name == "little" ] 

会报错:bash:too many arguments,因为$name只是简单的替换成[ little dog == "little" ] ,如果使用

name="little dog"
[ "$name" == "little" ] 

则实际使用的是[ "little dog" == "little" ]
案例二:
使用#@和#*
1、不使用“”的情况

"test.sh":

for i in #@:
	echo "i"
done
for i in #*:
	echo "i"
done

如果不加“”,#@和#都表示的是 $1 $2 $3…中间用空格连接,如果$1,$2这边变量内容中包含空格,则会被当成多个变量。如果执行./test.sh “aa bb” cc,二者输出的结果都是:
aa
bb
cc
如果使用的是“#@”和“#
”,前者表示的是“$1” “$2” “$3”…中间用空格连接,后者表示的是“$1 $2 $3…”,执行./test.sh “aa bb” cc,二者输出的结果分别为:
aa bb
cc
和:
aa bb cc

sc2181

直接校验退出码,而不是使用$?
有问题的代码

make mytarget
if [ $? -ne 0 ]
then
  echo "Build failed"
fi

正确的代码

if ! make mytarget
then
  echo "Build failed"
fi

shellcheck认为有以下几个原因要避免使用$?:

1、使用$?使代码冗余
2、命令的执行和结果的判断是分离的,很容易无意的造成判断失败,比如在make mytarget后面加一个echo打印,那么$?判断的对象就不是make mytarget了。
推荐的使用方式,如果对命令执行成功做处理,使用如下方式:

if mycommand; then ...

mycommand执行成功返回true。
如果对命令执行失败做处理,使用如下方式:

if ! mycommand; then ...

! mycommand表示返回false。

如何屏蔽shellcheck的建议

想要坚持自己想想法,不需要shellcheck的建议,可以使用disable

hexToAscii() {
  # shellcheck disable=SC2059
  printf "\x$1"
}
 类似资料: