将bash脚本源到另一个[重复]
Posted
技术标签:
【中文标题】将bash脚本源到另一个[重复]【英文标题】:Source bash script to another one [duplicate] 【发布时间】:2012-12-23 14:49:24 【问题描述】:可能重复:Reliable way for a bash script to get the full path to itself?
我有 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
方法)。
当我从<git_root>/scripts/
调用test.sh
脚本时,一切正常,但是一旦我更改当前工作目录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 ...
这就是我所拥有的:
search.sh
脚本到<git_root>
目录的相对路径
我想要什么:能够在<git_root>
内的任何地方运行test.sh
而不会出错。
P.S.:不能使用search.sh
的永久绝对路径,因为可以将 git 存储库克隆到任何位置。
【问题讨论】:
不重复。我尝试了此链接中的方法。但这不是我的情况,因为在这里我不需要获取我的test.sh
脚本的路径。
也许我说的很明显,但是如果您目前source
是当前目录的相对路径,那么从脚本路径中获取相对路径似乎是一个很好的改进。唯一的问题是如果用户将脚本完全移动到不同的位置,但我无法想象你会如何解决这个问题,除了使用环境变量。
如果search.sh
脚本与test.sh
位于同一目录中,那么找到test.sh
所在的路径肯定会有所帮助,因为您可以使用该路径来查找其他脚本.
【参考方案1】:
如果两个脚本都在同一个目录中,那么如果你得到运行脚本所在的目录,你就可以用它作为调用另一个脚本的目录:
# 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://***.com/a/4774063/440558
【讨论】:
似乎更容易做到SCRIPTPATH=$( readlink -f $0 )
【参考方案2】:
有没有办法识别这个 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
【讨论】:
但是如何避免类似 git 存储库的问题。不能保证有人做了git clone <link> first-git-repo
然后git clone <link> second-git-repo
。同样在一般情况下,此解决方案可能会花费太多时间来搜索此 git 存储库。同样在一般情况下,我们不仅应该使用$HOME
dir,还应该使用/ (root)
dir。
出于这些原因,我简化了任务。即使对于这个也找不到可靠的方法;)
您在第二个代码块的第二行缺少右括号。
@user966467 好的,你怎么知道 Git 存储库的位置?无论您找到该 Git 存储库的位置,都必须让您的程序知道。
我建议我可以使用@Joachim Pileborg 提到的meta.stackexchange.com/questions/14237207/…。【参考方案3】:
你可以这样做:
# Get path the Git repo
GIT_ROOT=`git rev-parse --show-toplevel`
# Load the search functions
source $GIT_ROOT/scripts/search.sh
How get Git root directory!
或者喜欢@Joachim Pileborg says,但是要注意一定要知道这个到另一个脚本的路径;
# 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"`
无论如何,你必须把这个sn-p放在所有使用其他脚本的脚本上。
【讨论】:
做任何其他方式,不使用可靠代码中的 git 功能,我必须使用git
命令的存在性检查。我的意思是在每个新脚本中我都必须使用一些重复的代码:检查git
的存在,获取GIT_ROOT
,等等...
如果用户不在 Git 存储库中怎么办?有没有办法找到 Git 本地存储库?
@DavidW。找到 Git 本地存储库最可靠的方法是在目录结构中向上移动,直到找到 .git
目录或找到某个已定义的目录,例如 $HOME
、/
等。
@sigmavirus24 我从 OP 中得知他正在使用的目录可能在 Git 存储库本身之外。例如,他在$HOME/bin
,但Git repo 在$HOME/work/git_repo
。
来自 OP:Both scripts are located in git repository.
... What I want: To have ability to run test.sh from anywhere inside <git_root> without errors.
【参考方案4】:
对于那些不想使用 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
【讨论】:
以上是关于将bash脚本源到另一个[重复]的主要内容,如果未能解决你的问题,请参考以下文章