通常包含脚本的方式是"source"

eg:

main.sh:

#!/bin/bash

source incl.sh

echo "The main script"

incl.sh:

echo "The included script"

执行“。/main.sh”的结果是:

The included script
The main script

... 现在,如果您试图从另一个位置执行该shell脚本,它将无法找到包含,除非它在您的路径中。

确保脚本能够找到包含脚本的好方法是什么,特别是在脚本需要可移植的情况下?


当前回答

我倾向于让我的脚本彼此相对。 这样我就可以使用dirname:

#!/bin/sh

my_dir="$(dirname "$0")"

"$my_dir/other_script.sh"

其他回答

如果在同一个目录下,你可以使用dirname $0:

#!/bin/bash

source $(dirname $0)/incl.sh

echo "The main script"

根据我的说法,脚本包含的合适位置是/usr/local/lib/

/usr/local/lib 与本地安装程序相关联的文件。

我个人更喜欢/usr/local/lib/bash/includes。 有bash-helper库用于以这种方式包含库:

#!/bin/bash

. /usr/local/lib/bash/includes/bash-helpers.sh

include api-client || exit 1                   # include shared functions
include mysql-status/query-builder || exit 1   # include script functions

# include script functions with status message
include mysql-status/process-checker; status 'process-checker' $? || exit 1
include mysql-status/nonexists; status 'nonexists' $? || exit 1

SRC=$(cd $(dirname "$0"); pwd)
source "${SRC}/incl.sh"

个人将所有库放在lib文件夹中,并使用导入函数来加载它们。

文件夹结构

script.sh内容

# Imports '.sh' files from 'lib' directory
function import()
{
  local file="./lib/$1.sh"
  local error="\e[31mError: \e[0mCannot find \e[1m$1\e[0m library at: \e[2m$file\e[0m"
  if [ -f "$file" ]; then
     source "$file"
    if [ -z $IMPORTED ]; then
      echo -e $error
      exit 1
    fi
  else
    echo -e $error
    exit 1
  fi
}

注意,这个导入函数应该在脚本的开头,然后你可以像这样轻松地导入你的库:

import "utils"
import "requirements"

在每个库(例如utils.sh)的顶部添加一行:

IMPORTED="$BASH_SOURCE"

现在您可以从script.sh访问utils.sh和requirements.sh中的函数

待办事项:编写一个链接器来构建一个sh文件

我把所有的启动脚本都放在。bashrc文件中。d目录。 这是在/etc/profile.之类的地方常用的技术d等。

while read file; do source "${file}"; done <<HERE
$(find ${HOME}/.bashrc.d -type f)
HERE

使用通配符解决方案的问题…

for file in ${HOME}/.bashrc.d/*.sh; do source ${file};done

...你的文件列表可能太长了。 一种方法是……

find ${HOME}/.bashrc.d -type f | while read file; do source ${file}; done

…运行但不按预期改变环境。