通常包含脚本的方式是"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脚本,它将无法找到包含,除非它在您的路径中。

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


当前回答

我知道我迟到了,但这应该工作,无论你如何开始脚本和使用内置专属:

DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/incl.sh"
. "$DIR/main.sh"

. (dot)命令是source的别名,$PWD是工作目录的路径,BASH_SOURCE是一个数组变量,其成员是源文件名,${string%substring}从$string后面删除$substring的最短匹配

其他回答

替代:

scriptPath=$(dirname $0)

is:

scriptPath=${0%/*}

. .优点是不依赖于dirname,这不是一个内置命令(在模拟器中并不总是可用)。

Steve的回答绝对是正确的技术,但它应该被重构,以便您的installpath变量在一个单独的环境脚本中,所有这些声明都是在该脚本中进行的。

然后,所有脚本都以该脚本为源,如果安装路径发生更改,则只需在一个位置更改它。让事情更,呃,不受未来影响。天啊,我讨厌这个词!(-):

顺便说一句,当你以你的例子中所示的方式使用它时,你应该使用${installpath}引用变量:

. ${installpath}/incl.sh

如果省略大括号,一些shell将尝试展开变量“installpath/ include .sh”!

这个问题的答案的组合提供了最健壮的解决方案。

它在产品级脚本中工作,支持依赖关系和目录结构:

#!/bin/bash

# Full path of the current script
THIS=`readlink -f "${BASH_SOURCE[0]}" 2>/dev/null||echo $0`

# The directory where current script resides
DIR=`dirname "${THIS}"`

# 'Dot' means 'source', i.e. 'include':
. "$DIR/compile.sh"

该方法支持所有这些:

路径中的空间 链接(通过readlink) ${BASH_SOURCE[0]}比$0更健壮

我们只需要找到include .sh和main.sh所在的文件夹;用下面的代码修改main.sh:

main.sh

#!/bin/bash

SCRIPT_NAME=$(basename $0)
SCRIPT_DIR="$(echo $0| sed "s/$SCRIPT_NAME//g")"
source $SCRIPT_DIR/incl.sh

echo "The main script"

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

#!/bin/sh

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

"$my_dir/other_script.sh"