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

Bash 如何在zsh中获取执行脚本的父文件夹?,bash,zsh,Bash,Zsh,在bash中,我通过此行获取执行脚本的父文件夹名称 SCRIPT_PARENT=`readlink -f ${BASH_SOURCE%/*}/..` 在zsh中是否有任何方法可以同时在zsh和bash中实现这一点 假设我有一个文件/some/folder/rootfolder/subfolder/script,内容如下: echo `magic-i-am-looking-for` 我想让它这样做: $ cd /some/other/folder $ . /some/folder/rootfo

在bash中,我通过此行获取执行脚本的父文件夹名称

SCRIPT_PARENT=`readlink -f ${BASH_SOURCE%/*}/..`
在zsh中是否有任何方法可以同时在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中不起作用,所以没有实现

所以基本上是:


有没有一种方法可以在zsh中模拟同样适用于BASH的
$BASH\u SOURCE

因为您可以从$PATH运行命令,我将这样做:

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

这是您想要的输出吗?

虽然在zsh中很容易做到这一点,但使用能够在zsh中评估的纯bash也同样容易。如果您不能使用任何可能在您的路径上或不在您的路径上的命令,那么您只能使用变量更改来实现您想要的:

SCRIPT_SOURCE=${0%/*}
这可能是一条相对的路径。如果确实需要完整路径,则必须求助于外部命令(您可以自己实现它,但要避免使用非常可用的命令,需要做大量工作):

这并不取决于$PATH,它只取决于/bin/readlink是否存在。几乎可以肯定的是

现在,您希望这是一个源文件。这很好,因为您可以只导出设置的任何变量,但是如果执行上述命令,那么$0将是源文件的位置,而不是调用脚本的位置

这只意味着您需要设置一个变量来保存源代码脚本知道的$0值。例如:

您将从以下来源获取的脚本:

echo ${LOCATION%/*}
源于该脚本的脚本:

LOCATION=$0
<source script here>
LOCATION=$0

但是考虑到${0%/*}扩展非常紧凑,您可以用它来代替脚本。

我现在意识到,zsh中的
$0
的行为类似于BASH中的
$BASH_SOURCE
。因此,在可用时使用
$BASH_SOURCE
,并返回到
$0
解决了我的问题:

${BASH_SOURCE:-$0}
当从
$PATH
寻源时,只剩下一个小zsh边案例,如:

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

我可以做一个
哪个脚本
,但这在其他情况下不太好

命令不一定在路径上。如果脚本来源于shell,它也会起作用。请提供预期输出的示例您是对的:
$0
是zsh的答案。不幸的是,由于bash没有设置
$0
,因此在寻源时,它在bash中的行为不同。请参考我的答案:
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