Bash zsh脚本获得脚本';s目录?

Bash zsh脚本获得脚本';s目录?,bash,zsh,Bash,Zsh,我想把这个bash脚本介绍翻译成zsh脚本。因此,我没有这方面的经验,我希望我能在这里得到帮助: bash脚本: SCRIPT_PATH="${BASH_SOURCE[0]}"; if([ -h "${SCRIPT_PATH}" ]) then while([ -h "${SCRIPT_PATH}" ]) do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done fi pushd . > /dev/null cd `dirname ${SCR

我想把这个bash脚本介绍翻译成zsh脚本。因此,我没有这方面的经验,我希望我能在这里得到帮助:

bash脚本:

SCRIPT_PATH="${BASH_SOURCE[0]}";
if([ -h "${SCRIPT_PATH}" ]) then
    while([ -h "${SCRIPT_PATH}" ]) do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
pushd . > /dev/null
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd  > /dev/null
我已经知道的是我可以使用
SCRIPT_PATH=“$0”以获取脚本所在的路径。但是我在“readlink”语句中出现了错误


感谢您的帮助

除了
BASH_源代码
之外,我看不到您需要做任何更改。但剧本的目的是什么?如果要获取脚本所在的目录,则有
${0:A:h}
:A
将解析所有符号链接,
:h
将截断最后一个路径组件,并为您留下目录名):

就这些。请注意,原始脚本有一些奇怪的地方:

  • if(…)
    而(…)
    在子shell中启动
    。这里不需要子shell,只需使用
    if…
    while…
    就可以更快地执行这些检查
  • pushd.
    根本不需要。使用
    pushd
    时,您通常会用它替换
    cd
    调用:

    pushd "$(dirname $SCRIPT_PATH)" >/dev/null
    SCRIPT_PATH="$(pwd)"
    popd >/dev/null
    
  • 如果
    输出带有空格的内容,
    cd```
    将失败。目录可能包含一个空格。在上面的示例中,我使用了
    “$(…)”
  • “`…`
    也可以使用
  • 您不需要尾随
  • 有<代码> RealLink -f<代码>,它将解决所有的链接,因此可以考虑将原始脚本还原为<代码> Script PTFATE =“$(DrimeNo.$(RealLink -F)${BasHySoal[0 ] }))“< /Cord>”(行为可能会因脚本似乎只在最后一个组件中解析SysLink而改变):这是BASH等价于代码> $ { 0:A:H} < /LI>
  • 如果[-h“$SCRIPT\u PATH”]
    是冗余的,因为除非脚本路径是符号链接,否则将不会执行具有相同条件的
    正文
  • readlink$SCRIPT\u PATH
    将返回相对于包含
    $SCRIPT\u PATH
    的目录的符号链接。因此,原始脚本不可能用于解析最后一个组件中的符号链接
  • 没有
    介于
    如果(…)
    之间,则
    。我很惊讶bash接受了这一点
  • 以上所有语句都适用于bash和zsh

    如果只解析最后一个组件中的符号链接是必要的,您应该这样写:

    SCRIPT_PATH="$0:a"
    function ResolveLastComponent()
    {
        pushd "$1:h" >/dev/null
        local R="$(readlink "$1")"
        R="$R:a"
        popd >/dev/null
        echo $R
    }
    while test -h "$SCRIPT_PATH" ; do
        SCRIPT_PATH="$(ResolveLastComponent "$SCRIPT_PATH")"
    done
    


    为了说明第7条语句,有以下示例:

  • 创建目录
    $R/bash
    $R
    是任何目录,例如
    /tmp
  • 将脚本放在那里,不做任何修改,例如,在name
    $R/bash/script\u path.bash
    下。在其末尾添加行
    echo“$SCRIPT_PATH”
    ,并添加行
    #/bin/bash
    在开始测试时
  • 使其可执行:
    chmod+x$R/bash/script\u path.bash
  • 创建指向它的符号链接:
    cd$R/bash&&ln-s script\u path.bash链接
  • cd$R
  • 启动
    $R/bash/1
    。现在,您将看到脚本输出
    $R
    ,而它应该像启动
    $R/bash/script\u path.bash
    时一样输出
    $R/bash
  • 使用“-x”运行以打印出正在定义(和未定义)的变量,并从中进行调试。你的脚本简短明了,应该不难。依我拙见
    SCRIPT_PATH="$0:a"
    function ResolveLastComponent()
    {
        pushd "$1:h" >/dev/null
        local R="$(readlink "$1")"
        R="$R:a"
        popd >/dev/null
        echo $R
    }
    while test -h "$SCRIPT_PATH" ; do
        SCRIPT_PATH="$(ResolveLastComponent "$SCRIPT_PATH")"
    done