2015-10-06 39 views
2

我想要一个源代码的shell脚本来确定它自己的位置,并且我发现这对于破折号来说是一项艰巨的任务。如何找到脚本作为源代码的路径?

在bash,sh和csh中,我可以使用:$_

在鱼,我可以使用(status -f)

在短跑,我有没有运气...

我试图采购结果如下如下所示的path.sh文件:

# path.sh 
called=$_ 
echo called:  $called 
echo underscore: $_ 
echo zero:  $0 
echo dash_source: $DASH_SOURCE 
echo bash_source: $BASH_SOURCE 

dash -c ". path.sh"

输出:

called:  /usr/local/bin/dash 
underscore: /usr/local/bin/dash 
zero:  dash 
dash_source: 
bash_source: 

我怎样才能得到破折号path.sh的路径?

回答

2

似乎没有任何便携式(POSIX标准)的方式来做到这一点。

POSIX表示采购为“dot脚本”。尽管shell语言参考的其他几个部分都讨论了“点脚本”,但这些实例都没有提供任何方式来找出当前正在执行的点脚本的路径。特别是,$0保留给“shell脚本”,这与“点脚本”不同。 “来源”一词不会以任何大小写形式出现在页面上,也不会出现在任何较大的单词中(因此不会出现$BASH_SOURCE类似的东西)。影响外壳的标准环境变量都不相关。我要说的是在POSIX规范中这是不可能的。由于Dash紧跟在POSIX后面,所以对于这种特定情况不太可能有Dashism(如果要这样做,它会借用$BASH_SOURCE或创建类似变量)。

+0

因此,如果用户碰巧正在运行破折号外壳,我必须要求他们从特定路径中获取我的文件? – ben

+0

您可以在脚本中硬编码路径,但在您的情况下这可能不可行。你为什么需要知道路径?你还有其他的文件要去找吗? – Kevin

+0

准确地说 - 我需要为项目主页设置一个环境变量,然后访问与该路径相关的一些其他文件。硬编码绝对路径不是一种选择。 – ben

1

这在POSIX shell标准下是不可能的(dash只实现了,除此之外)。 .是一个内置的而不是shell脚本,因此,$0位置参数引用.的调用方,而$1引用该调用方的参数(如果存在)。尤其是,这些内容都不是指.本身或其参数脚本。

0

如果您可以更改源代码,请在所有源调用之前添加此函数。

.() { 
    command . "$1" 
} 
. script.sh 
# more dot scripts 

现在在函数内部挂钩'点脚本'函数是什么,位置参数是函数参数。 所以你的源脚本中,位置参数是:

.   # $0 
script.sh # $1 

脚本里面正在来源:

# script.sh 
echo "$(basename "$1")"  # this is the name of the script itself 
0

我同意接受的答案,但我可以使它工作使用lsof的:

x=$(lsof -p $$ -Fn0 | tail -1); script=${x#n} 

这是可行的,因为破折号在执行时保持脚本打开。这需要是脚本的第一行,否则如果短划线打开其他文件描述符,它可能会失败。