获取脚本目录的bash脚本的zsh等价物是什么?

时间:2013-09-15 08:34:51

标签: 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 ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd  > /dev/null

我已经知道的是我可以使用 SCRIPT_PATH="$0";获取脚本所在的路径。但后来我的“readlink”声明出错了。

感谢您的帮助

1 个答案:

答案 0 :(得分:6)

BASH_SOURCE外,我发现您无需进行任何更改。但脚本的目的是什么?如果你想获取你的脚本所在的目录${0:A:h}:A将解析所有符号链接,:h将截断最后一个路径组件,留下你的目录名称):

SCRIPT_PATH="${0:A:h}"

就是这样。请注意,原始脚本有一些奇怪的事情发生:

  1. if(…)while(…)在子shell中启动。这里不需要子shell,只使用if …while …进行这些检查会更快。
  2. 根本不需要
  3. pushd .。在使用pushd时,您通常会将cd来电替换为:

    pushd "$(dirname $SCRIPT_PATH)" >/dev/null
    SCRIPT_PATH="$(pwd)"
    popd >/dev/null
    
  4. 如果cd `…`输出带空格的内容,则
  5. 将失败。目录可以包含空格。在上面的示例中,我使用了"$(…)""`…`"也可以使用。
  6. 您不需要在变量声明中追踪;
  7. readlink -f将解析所有符号链接,因此您可以考虑将原始脚本缩减为SCRIPT_PATH="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))"(行为可能会因脚本似乎仅在最后一个组件中解析符号链接而改变):这是等效的bash到${0:A:h}
  8. if [ -h "$SCRIPT_PATH" ]是多余的,因为除非脚本路径是符号链接,否则不会执行具有相同条件的while正文。
  9. readlink $SCRIPT_PATH将返回相对于包含$SCRIPT_PATH 的目录的符号链接。因此,原始脚本不可能用于解析最后一个组件中的符号链接。
  10. ;if(…)之间没有then。我很惊讶bash接受这个。
  11. 以上所有陈述均适用于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条陈述,有以下例子:

    1. 创建目录$R/bash$R是任何目录,例如/tmp)。
    2. 将您的脚本放在那里,不做任何修改,例如名称$R/bash/script_path.bash下。在其末尾添加行echo "$SCRIPT_PATH",并在开始时添加行#!/bin/bash进行测试。
    3. 使其可执行:chmod +x $R/bash/script_path.bash
    4. 为其创建符号链接:cd $R/bash && ln -s script_path.bash link
    5. cd $R
    6. 启动$R/bash/1。现在,您将看到您的脚本输出$R,同时输出$R/bash,就像您启动$R/bash/script_path.bash时一样。