运行前进行完整的 bash 脚本检查

运行前进行完整的 bash 脚本检查

尝试在 bash 脚本中实现自我语法检查,test.sh 以便在执行脚本之前运行语法检查。

error_exit()
{
        echo -e "$1" 1>&2
        exit 1
}
bash -n "$(basename $BASH_SOURCE)"
RESULT=$?
if [ $RESULT == 0 ]; then
  echo "[OK] Test pass"
else
  error_exit "Something is not right :( \n check the sytntax"
fi
starting-script

bash -nbash -x,如果存在一些严重的语法错误,但有轻微的错误,则效果 相同,例如:

echo "somthing" && sleep5&&
./test.sh: line 14: sleep5: command not found

被忽略……

有没有办法进行完整的语法检查,另外还可以在某种“沙盒模式”/“模拟模式”下运行脚本来捕获所有可能的错误,并返回错误(如果有)?

編輯 在脚本必须将部分脚本复制到远程服务器的情况下,例如在数百个从属服务器(受监控服务器)上安装 nagios 的脚本等。不幸的是,文本复制并不总是顺利的,在自动将脚本复制为文本时可能会发生错误,因此,如果检测到任何错误,检查并结束脚本非常重要。

答案1

正如@techraf 和@Wice22 指出的那样,运行时不存在完整的检查。

不过,您可以为 Bash 脚本创建“单元”测试。BATS 是一个可以提供帮助的框架:https://github.com/sstephenson/bats
CI 系统可以在你的 git repo 的每次提交上运行这些测试,这样你就可以在那些脚本投入生产之前看到你是否搞砸了。

但是 BATS 没有对您的脚本进行自动测试,而是您必须自己实施每个测试。

编辑:关于您的编辑:您可以创建要复制的脚本的 md5sum,复制它们(远程脚本和 md5sum 文件)并远程检查脚本是否仍然与 md5sum 匹配。

答案2

你可以看看壳牌检测该项目对 shell 脚本语法进行了更彻底的验证;包括最佳实践和潜在的陷阱。

但是,即使 ShellCheck 也不会将你问题中的示例报告为不正确,因为没有语法错误。

sleep5您正在调用一个语法上有效的操作的外部命令。

使用变量并在调用命令之前检查命令是否存在,如果不存在则正常失败。

答案3

据我所知,bash 中没有“沙盒模式”,没有 try/catch 程序。要捕获 bash 中的错误,您需要运行脚本。试试这个帖子https://stackoverflow.com/questions/22009364/is-there-a-try-catch-command-in-bash 您可以通过使用子 shell 来模拟救援,如图所示,使用该技术,如果检测到“异常”,您可以在任何时候停止脚本,但这不是模拟。所以它会是这样的:

#!/bin/bash
script_name=$(basename $0)
error_exit() { echo -e "${script_name} file:  ${1:-"Unknown Error"}" 1>&2
exit 1
}
bash -n "$(basename $BASH_SOURCE)"
RESULT=$?
if [ $RESULT == 0 ]; then
  echo $" ${green}[OK] Test pass${reset} "
else
  error_exit "syntax error detected"
fi
echo "Check pass ok"

bash -e <<TRY
  echo "" && sleep5
  echo"and_somthing else"
  echo"and_some_more stuff"
  echo"and some_more"
TRY
if [ $? -ne 0 ]; then
  error_exit "error detected"
fi
echo "continuing if all goes well"

相关内容