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屏蔽。 以下记录今天遇到的几个错误,就属于第二种情况:
我的源代码类似:
cd foo
function()
cd -
shellcheck认为这是有问题的,根本原因是,cd命令可能 因为各种原因失败,比如拼写错误,缺少路径,缺少权限以及软连接失效等等;当出现这些情况,而脚本继续执行的话,那么所有的操作都是在错误的路径下执行的,想想如果function()在错误的路径下执行了一些删除文件的操作,想想都头大。
解决建议:
cd foo || exit
cd foo || { echo "Failure"; exit 1;}
if cd foo; then echo "Ok"; else echo "Fail"; fi
cd foo && function()
使用双引号“”保持你想要的变量内容是一个整体。
在使用变量的时候,最好用“”把它引起来,如果不用“”,变量内容中有空格,会造成出乎意料的结果。
案例一:
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
直接校验退出码,而不是使用$?
有问题的代码
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的建议,可以使用disable
hexToAscii() {
# shellcheck disable=SC2059
printf "\x$1"
}