我怎么在bash中source_once?

时间:2015-06-04 21:31:18

标签: bash

什么是在bash中一次采购的好方法。

bash是否存储了源文件的路径,或者我是否需要使所有source / .调用通过一个存储这些路径的包装器?

是否有一个标准可用的机制可以找到源参数解析的内容?除非文件是可执行的,否则which似乎无法正常工作。

2 个答案:

答案 0 :(得分:6)

在您可能提供的每个文件中,添加一个语句。假设文件/etc/interface是您想要只提取一次的文件之一,然后按如下格式化该文件:

if [ ! "$ETC_INTERFACE" ]
then
    # statements that you
    # want to source...
fi
export ETC_INTERFACE=Yes

这可以确保/etc/interface中的语句只执行一次。如果脚本尝试再次获取它,它将看到已设置ETC_INTERFACE并跳过文件正文。

替代方法

假设一个人不想修改要获取的文件,但可以修改源代码的脚本。在这种情况下,请按如下方式获取:

[ ! "$ETC_INTERFACE" ] && source /etc/interface && export ETC_INTERFACE=Yes

答案 1 :(得分:0)

以下是我如何解决它:

#Store source-in paths in a global hash
declare -A SOURCES

#Resolve paths manually
path_resolve(){
  #Absolute paths resolve to themselves
  [[ "$1" =~ ^/ ]] && { echo "$1"; return 0; }

  #Otherwise resolve against $PWD and then $PATH items
  local search_path=$PWD:$PATH
  local IFS=:
  for p in $search_path; do
    [[ -r "$p/$1" ]] && { echo "$p/$1"; return 0; }
  done
  return 1
}

#Helper function
warn(){ echo >&2 "$@"; }

#AKA source_once AKA include_once
require(){
  local path=$(path_resolve "$1")
  [[ -z "${SOURCES["$path"]}" ]] && {
    SOURCES["$path"]=true
    . "$path"
    return 0
  }
  #Warn if a second `source` is attempted from the main scope of an interactive session
  [[ -z "${BASH_SOURCE[0]}" ]] && {
    warn "$path already sourced in"
    warn "Use \`. '$1'\` to reload it"
  }
  return 1
}

#AKA source_relative_once AKA include_relative_once
#require relative to current file or $PWD if there's no current file
require_relative() {
 local dir="${BASH_SOURCE%/*}"
 [[ -z "$dir" ]] && dir="$PWD"
 require "$dir/$1"
}

#source relative to current file or $PWD if there's no current file
source_relative() {
 local dir="${BASH_SOURCE%/*}"
 [[ -z "$dir" ]] && dir="$PWD"
 source "$dir/$1"
}