7

可能重复:
bash 脚本获取自身完整路径的可靠方法?

我有 bash 脚本test.sh,它通过以下几行使用另一个search.sh脚本中的函数:

source ../scripts/search.sh
<call some functions from search.sh>

这两个脚本都位于 git 存储库中。search.sh<git_root>/scripts/目录中,test.sh位于同一目录中(但一般来说,可以位于<git_root>目录内的任何位置 - 我的意思是我不能依赖以下source search.sh方法)。

当我从一切正常调用test.sh脚本时<git_root>/scripts/,但只要我更改当前工作目录test.sh就会失败:

cd <git_root>/scripts/
./test.sh         //OK
cd ..
./scripts/test.sh //FAILS
./scripts/test.sh: line 1: ../scripts/search.sh: No file or directory ...

因此我所拥有的:

  1. search.sh脚本到<git_root>目录的相对路径

我想要什么:能够test.sh从内部任何地方运行<git_root>而不会出错。

PS:无法使用永久绝对路径,search.sh因为 git 存储库可以克隆到任何位置。

4

4 回答 4

3

如果两个脚本都在同一个目录中,那么如果你得到运行脚本所在的目录,你可以使用它作为调用另一个脚本的目录:

# Get the directory this script is in
pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd -P`
popd > /dev/null

# Now use that directory to call the other script
source $SCRIPTPATH/search.sh

取自问题的已接受答案,我将此问题标记为重复:https ://stackoverflow.com/a/4774063/440558

于 2013-01-09T14:23:46.670 回答
1

你可以这样做:

# Get path the Git repo
GIT_ROOT=`git rev-parse --show-toplevel`

# Load the search functions
source $GIT_ROOT/scripts/search.sh

如何获取 Git 根目录

或者像@Joachim Pileborg 所说的那样,但你必须注意你必须知道这个到另一个脚本的路径;

# Call the other script
source $SCRIPTPATH/../scripts/search.sh
# Or if it is in another path
source $SCRIPTPATH/../scripts/seachers/search.sh

Apache Tomcat 脚本使用这种方法:

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

PRGDIR=`dirname "$PRG"`

无论如何,您必须将此代码段放在使用其他脚本的所有脚本上。

于 2013-01-09T14:53:23.910 回答
1

有没有办法识别这个 Git 存储库位置?环境变量集?您可以PATH在脚本本身中设置以包含 Git 存储库:

 PATH="$GIT_REPO_LOCATION/scripts:$PATH"
 . search.sh

脚本完成后,您PATH将恢复到其旧值,并且$GIT_REPO_LOCATION/scripts不再是PATH.

问题是找到这个位置开始。我想你可以在你的脚本中做这样的事情:

GIT_LOCATION=$(find $HOME -name "search.sh" | head -1)
GIT_SCRIPT_DIR=$(dirname $GIT_LOCATION)
PATH="$GIT_SCRIPT_DIR:$PATH"
. search.sh

顺便说一句,既然$PATH设置好了,我可以通过search.sh而不是./search.sh你在脚本目录中时必须做的调用脚本,并且你PATH没有包括.哪个是当前目录(并且 PATH 不应该包括.,因为它是一个安全漏洞)。

另请注意,您也可以搜索.git目录,这可能是您正在寻找的 Git 存储库:

GIT_LOCATION=$(find $HOME -name ".git" -type d | head -1)
PATH="$GIT_LOCATION:$PATH"
. search.sh
于 2013-01-09T15:08:43.460 回答
0

对于那些不想使用 git 的功能来查找父目录的人。如果你可以确定你总是在 git 目录中运行脚本,你可以使用这样的东西:

git_root=""
while /bin/true ; do
    if [[ "$(pwd)" == "$HOME" ]] || [[ "$(pwd)" == "/" ]] ; then
        break
    fi

    if [[ -d ".git" ]] ; then
        git_root="$(pwd)"
        break
    fi

    cd ..
done

我没有对此进行测试,但它只会循环返回,直到它到达您的主目录或 / 并且它会查看.git每个父目录中是否有一个目录。如果有,它会设置git_root变量并且它会爆发。如果它没有找到,git_root将只是一个空字符串。然后你可以这样做:

if [[ -n "$git_root" ]] ; then
    . ${git_root}/scripts/search.sh
fi

IHTH

于 2013-01-09T15:42:01.367 回答