我正在编写一个脚本来编译代码。这些来源位于许多不同的目录中。我将发布源代码,我希望它可以被许多其他人编译。因此,在我的脚本中,我使用相对路径
如果有人在他的机器上运行脚本,则从脚本所在的目录开始,例如./script
一切正常。但是,如果脚本是从另一个目录运行的,例如./path/to/script
,则路径不正确,脚本不起作用。
我怎么能克服这个?
答案 0 :(得分:6)
#!/bin/bash
scriptdir="$(dirname "$0")"
cd "$scriptdir"
所有以下代码都会像在脚本目录中运行一样发生。
请注意,这是关于导致脚本运行
这是我怀疑你想要的,因为它是一个用于编译的脚本,因此它将被放置在src树中的一个非常特定的文件夹中(例如configure
脚本或makefile的形式)
$0
是正在运行的脚本的完整路径。
bash
人(我添加的格式):
特殊参数
shell专门处理几个参数。这些参数可能 只被引用;不允许分配给他们。
....
0 扩展为shell或shell脚本的名称。这是设置为 shell初始化。
如果使用命令文件调用bash, $ 0 设置为该文件的名称 。
如果使用-c
选项启动bash,则设置$ 0 到了要执行的字符串之后的第一个参数,如果是 当下。否则,它被设置为用于调用bash的文件名
, 由零参数给出。
dirname
返回其参数的路径
cd
更改当前目录 因此,此代码位于顶部的每个脚本都将正在运行,就像当前在该目录中键入./script
一样。
对于质量控制和冗余错误检查的度量,您可能希望实现一个包装函数,该函数检查特定文件夹结构或某些文件的存在,以指示一切正确。 (无论出于何种原因,dirname
和cd
命令都不起作用 - 我在本文的底部有一个Mac示例。这个概念有两个方面:
例如:
runcheck () {
versioncheck () {
head -n1 version | grep -q "### myapp V"
}
backout () {
echo "Problem verifying source paths. Are you sure your archive is complete?"
exit
}
[ -d ./src ] && [ -d ./docs ] && [ -d ../myapp ] && (versioncheck) || backout
return
}
该代码将检查以下内容:
src
与可执行脚本docs
与可执行脚本myapp
存在于从可执行脚本向下一级的路径中version
的文件,并且第一行包含字符串### myapp V
(例如,对于{{} 1}}文件,其顶行可能为:version
)然后,您可以将命令### myapp V1.4 ###
放在脚本中的任意位置,以确认您位于正确的位置:
runcheck
附注/补充:这对#!/bin/bash
scriptdir="$(dirname "$0")"
cd "$scriptdir"
runcheck () {
versioncheck () {
head -n1 version | grep -q "### myapp V"
}
backout () {
echo "Problem verifying source paths. Are you sure your archive is complete?"
exit
}
[ -d ./src ] && [ -d ./docs ] && [ -d ../myapp ] && (versioncheck) || backout
return
}
runcheck #initial check at start of script
## bunch of code
## goes here
runcheck #just checking again
## bunch of code
## goes here
runcheck #final check before really doing something bad
## end of script
起作用,因为不需要彻底检查脚本文件的符号链接等。(再次......)便携式源代码tarball等,我非常怀疑是这样的。)
我建议阅读此主题:Getting the source directory of a Bash script from within 如果您想要或者需要彻底了解这个主题,可以更全面地应用它。
我再次使用您所知道的为您所需的内容量身定制 - 例如,使用bash
可能会被认为通常更强“健壮”,但是,在Mac OS X上,这将为您提供dirname "$(readlink -f "$0")"
,并且对于可移植脚本没有任何实际好处,但更适用于引用可能符号链接和/或包含在$ PATH目录中的已安装二进制文件的位置