在shell脚本中只包含一次脚本

时间:2014-05-31 12:06:19

标签: bash shell

我想将文件包含在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 ++那样。虽然这确实是一个好主意,但我想保持我的代码尽可能小,我并不真正关心数组迭代的性能。

我真的想知道是否有另一种方式,或者我在代码中做错了可修复的方法。提前谢谢!

4 个答案:

答案 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;