尝试在 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 -n
bash -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"