如何在zsh中获取执行脚本的父文件夹?

9
在bash中,您可以通过以下命令获取执行脚本的父文件夹名称:
SCRIPT_PARENT=`readlink -f ${BASH_SOURCE%/*}/..`

有没有办法以一种同时在zsh和bash中都能使用的方式来实现这一点?

假设我有一个文件/some/folder/rootfolder/subfolder/script,其内容如下:

echo `magic-i-am-looking-for`

我希望它能够表现出这样的行为:
$ cd /some/other/folder
$ . /some/folder/rootfolder/subfolder/script
/some/folder/rootfolder
$ . ../../folder/rootfolder/subfolder/script
/some/folder/rootfolder
$ cd /some/folder/rootfolder
$ . subfolder/script
/some/folder/rootfolder
$ cd subfolder
$ . script
/some/folder/rootfolder

这个应该在bash和zsh中都能工作。我的第一个实现了这种行为,但是由于$BASH_SOURCE在zsh中无法工作。

所以基本上就是:

是否有一种方法来模拟$BASH_SOURCE在zsh中也能工作,并且在bash中也能工作?


1
请提供带有预期输出的示例。 - shkschneider
3个回答

14
我现在意识到,在zsh中,$0的行为类似于bash中的$BASH_SOURCE。因此,当$BASH_SOURCE可用时使用它,否则退而求其次使用$0可以解决我的问题:
${BASH_SOURCE:-$0}

还有一个小的zsh边缘情况,当从$PATH引用时:

zsh> cat ../script
echo \$0: $0
echo \$BASH_SOURCE: $BASH_SOURCE
echo '${BASH_SOURCE:-$0}:' ${BASH_SOURCE:-$0}
zsh> . script
$0: script
$BASH_SOURCE:
${BASH_SOURCE:-$0}: script
bash> . script
$0: bash
$BASH_SOURCE: /home/me/script
${BASH_SOURCE:-$0}: /home/me/script

我可以执行 which script 命令,但这样做会影响其他情况。

2
请参考我的答案:https://dev59.com/2Gkw5IYBdhLWcg3wbp8S#23259585 - Hui Zheng

9

虽然在zsh中做到这一点很容易,但使用纯bash同样容易,并且可以在zsh中进行评估。如果您不能使用可能位于路径上的任何命令,则只能使用变量修改来实现您想要的效果:

SCRIPT_SOURCE=${0%/*}

这很可能是一个相对路径。如果你真的想要完整的路径,那么你就需要使用外部命令(你可以自己实现,但是为了避免使用非常常见的命令会需要很多工作):

SCRIPT_SOURCE=$(/bin/readlink -f ${0%/*})

这并不依赖于你的$PATH,只取决于/bin/readlink是否存在。它几乎肯定存在。
现在,您希望这是一个被源文件调用的文件。这很好,因为您可以导出设置的任何变量,但是如果执行上述操作,则$0将是源文件的位置,而不是调用脚本的位置。
这意味着您需要设置一个变量来保存$s0值,源脚本知道该变量。例如:
您将要源代码的脚本:
echo ${LOCATION%/*}

源该脚本的脚本:
LOCATION=$0
<source script here>

但是考虑到${0%/*}扩展非常简洁,您可以直接在脚本中使用它。


1
你是对的:在zsh中,$0是答案。不幸的是,在bash中,当作为源代码运行时,它的行为与zsh不同,因为bash不会设置$0 - don_jones

0

因为您能够从$PATH运行命令,所以我会做类似的事情:

SCRIPT_PARENT=$(readlink -f "$(which $0)/..")

这是你期望的输出吗?


1
该命令不一定在路径上。如果脚本被引入到shell中,它也应该能够正常工作。 - don_jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接