我想将文件包含在shell脚本中作为"支持"脚本。由于他们设置并检查环境,我只想让它们执行一次。
我的方法是创建一个全局数组,检查该数组中是否存在脚本名称。如果没有,请将其添加到数组中,然后输入"来源"外部文件。
目前的代码如下:
function array_contains() { # array, value
local element
for element in $1; do
[[ "$element" == "$2" ]] && return 0
done
return 1
}
declare -a LOADED_SUPPORT_SCRIPTS
function require_support() { # file
# Check if we loaded the support already
array_contains ${LOADED_SUPPORT_SCRIPTS[@]} $1 && return 0
# Add loaded support to array
LOADED_SUPPORT_SCRIPTS=("${LOADED_SUPPORT_SCRIPTS[@]}" "$1")
log -i "Including support for '$1'"
source "$BASE_DIR/supports/$1.sh"
return 1
}
虽然这应该在理论上起作用(至少对我而言),但这段代码每次都会失败。不知怎的,数组被重置(即使我从来没有在其他地方访问它)并且总是包含" /"进入开头。
从进一步谷歌搜索我的问题,我发现this "solution"需要在我想要包含的每个脚本中都有一个新的变量名称 - 就像C / C ++那样。虽然这确实是一个好主意,但我想保持我的代码尽可能小,我并不真正关心数组迭代的性能。
我真的想知道是否有另一种方式,或者我在代码中做错了可修复的方法。提前谢谢!
答案 0 :(得分:2)
也许您可以尝试使用 Shell Script Loader 。在一个着名的类似帖子中查看有关它的帖子:https://stackoverflow.com/a/3692080/445221。
答案 1 :(得分:2)
您可以检查是否存在您希望由支持脚本创建的功能。例如,如果您在其中包含的方法(至少一个)之后命名支持脚本:
for path in supports/*.sh
do
file="$(basename "$path")"
function="${file%.sh}"
if ! declare -F "$function"
then
source "$path"
fi
done
答案 2 :(得分:0)
您不需要“货源方”的控件,您可以拥有本身的脚本控件。
只需在脚本的开头仅添加一次即可添加以下内容(将“ MY_LIB”替换为唯一的名称):
#!/bin/bash
while read line; do
echo ${line}
fields=( ${line} )
if [ ${fields[2]} == "STOPPED" ]; then
echo "It's stopped."
fi
done < $(sudo supervisorctl status)
如果以后要启用该选项以再次获得它,则可以使用:
[ ! -z "${MY_LIB}" ] && return; MY_LIB=0
如果要动态检查客户端脚本中是否提供该脚本,请使用相同的基本逻辑:
unset MY_LIB
答案 3 :(得分:0)
@BuvinJ我喜欢您的解决方案,但使它起作用的唯一方法是添加export
,例如:
[ -n "${MY_LIB}" ] && return; export readonly MY_LIB=0;