关于shell:输出源bash脚本到另一个

Source bash script to another one

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Reliable way for a bash script to get the full path to itself?

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

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

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

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

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

所以我有:

  • search.sh脚本到目录的相对路径
  • 我想要的是:能够从内的任何地方运行test.sh,而不会出错。

    P.S.:不可能使用到search.sh的永久绝对路径,因为Git存储库可以克隆到任何位置。


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

    1
    2
    3
    4
    5
    6
    7
    # 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的副本。


    是否有方法标识此Git存储库位置?环境变量集?您可以在脚本本身中设置PATH以包括git存储库:

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

    一旦脚本完成,您的PATH将恢复到原来的值,而$GIT_REPO_LOCATION/scripts将不再是PATH的一部分。

    问题是首先要找到这个位置。我想你可以在剧本里这样做:

    1
    2
    3
    4
    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而不是在scripts目录中的./search.sh来调用脚本,你的PATH没有包括当前目录的.(路径不应该包括.,因为它是一个安全漏洞)。

    另一个注意事项是,您也可以搜索.git目录,该目录可能是您要查找的git存储库:

    1
    2
    3
    GIT_LOCATION=$(find $HOME -name".git" -type d | head -1)
    PATH="$GIT_LOCATION:$PATH"
    . search.sh


    你可以这样做:

    1
    2
    3
    4
    5
    # Get path the Git repo
    GIT_ROOT=`git rev-parse --show-toplevel`

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

    如何获取git根目录!

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

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

    ApacheTomcat脚本使用以下方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 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"`

    无论如何,您必须将这个片段放到所有使用其他脚本的脚本上。


    对于那些不愿意使用git的特性来查找父目录的人来说。如果您可以确保始终在git目录中运行脚本,则可以使用如下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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将只是一个空字符串。然后你可以做:

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

    伊希思