我正在编写一个bash脚本来配置NFS服务器。我能够手动配置NFS服务器,它功能齐全。现在我想在bash脚本中重现相同的步骤。我有所有的步骤和每一步,shell命令,我把一个bash函数。然后我有一个主要部分,我在那里进行函数调用,总共有16个函数。在主要部分我想检查函数返回值,通常只是“$?”值
if [ "function_1" -eq "0" ]; then
echo "Success"
else
echo "Failure"
fi
由于有16个函数调用,其中每个函数调用依赖于以前的函数成功,整个事情变得有点不整洁
if [ "function_1" -eq "0" ]; then
if [ "function_2" -eq "0" ]; then
if [ "function_3" -eq "0" ]; then
if [ "function_..." -eq "0" ]; then
if [ "function_16" -eq "0" ]; then
我的问题是,这是构建程序的正确方法,还是最好不要使用函数,只需在主要部分进行命令验证
chmod -R 0755 $SHARED_FILE_SYSTEM
if [ "$?" -eq "0" ]; then
echo "Success"
else
echo "Failure
fi
一个选项是制作一个函数列表并在循环中运行它们,如Shellcheck-clean代码所示:
#! /bin/bash -p
# ...
config_functions=(
function_1
function_2
# ...
function_15
function_16 )
for cfunc in "${config_functions[@]}" ; do
if "$cfunc" ; then
printf 'Success: %s\n' "$cfunc"
else
printf 'Failure: %s (%d)\n' "$cfunc" "$?"
fi
done
$?
,如果你这样做,Shellcheck会发出警告。见Shellcheck SC2181。break
的“Failure”分支中根据需要添加exit "$?"
或if
。如果函数接受参数,这种方法也很有效,但前提是参数始终相同。 (只需在循环中将参数添加到函数调用中。)如果不同的函数采用不同的参数,则效果较差。您可以尝试将完整的函数调用放在数组中的字符串中,但处理需要引用的参数很棘手。
如果函数接受参数(并且不同的函数采用不同的参数),简化命令验证的一种方法是使用函数来执行:
#! /bin/bash -p
# ...
# Run a configuration command (passed as arguments) and report if it succeeds or
# fails. Call 'exit' if the command fails.
function doconf
{
if "$@" ; then
printf 'Success: %s\n' "$*"
return 0
else
local status=$?
printf 'Failure: %s (%d)\n' "$*" "$status"
exit "$status"
fi
}
doconf function_1 arg1
doconf function_2 arg2a arg2b
# ...
doconf function_15 arg15a arg15b arg15c arg15d
doconf function_16 arg16a arg16b arg16c
如果你不希望程序在函数失败时立即退出,你可以通过将exit
调用放在子shell中来捕获doconf
完成的doconf
:
# ...
(
doconf function_1 arg1
doconf function_2 arg2a arg2b
# ...
doconf function_15 arg15a arg15b arg15c arg15d
doconf function_16 arg16a arg16b arg16c
)
# Program execution continues here, even if a `doconf` exits
# ...
doconf
不是一个好名字。您可能想要更改它。doconf
应该检查以确保提供至少一个参数(命令名称)。这是检查$?
的反模式。最好直接在if
语句中测试命令:
if cmd; then
...
fi
有明确的if
检查和错误消息是笨拙的。避免它的常见模式是在命令失败时简单地退出并依赖命令打印自己的错误消息。您不需要自己打印任何东西。然后你可以使用|| return
或|| exit
来挽救命令失败,其中a || b
是if ! a; then b; fi
的简写。
function_1 || exit
function_2 || exit
function_3 || exit
...
请注意,return
和exit
将自动使用$?
。
如果要在任何命令失败时退出,更简单的选择是使用errexit
启用set -e
标志。这样做,shell将自动退出脚本,而无需插入繁琐的检查。
set -e
function_1
function_2
function_3
...