bsh脚本获取脚本目录的zsh等效项是什么? [英] What is the zsh equivalent of a bash script getting the script's directory?

查看:183
本文介绍了bsh脚本获取脚本目录的zsh等效项是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将此bash脚本翻译为zsh脚本.因此,我对此没有经验,希望可以在这里获得帮助:

I want to translate this bash-script intro a zsh-script. Hence I have no experience with this I hope I may get help here:

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"语句出现了错误.

What I already know is that I can use SCRIPT_PATH="$0"; to get the path were the script is located at. But then I get errors with the "readlink" statement.

感谢您的帮助

推荐答案

除了BASH_SOURCE,我看不到需要进行任何更改.但是脚本的目的是什么?如果要获取目录,脚本位于${0:A:h}(:A将解析所有符号链接,:h将截断最后一个路径组件,并为您提供目录名称):

Except for BASH_SOURCE I see no changes that you need to make. But what is the purpose of the script? If you want to get directory your script is located at there is ${0:A:h} (:A will resolve all symlinks, :h will truncate last path component leaving you with a directory name):

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

仅此而已.请注意,原始脚本会发生一些奇怪的事情:

and that’s all. Note that original script has something strange going on:

  1. if(…)while(…)在子Shell中启动.您无需在这里使用subshel​​l,只需使用if …while …进行这些检查就会更快.
  2. 完全不需要
  3. pushd ..使用pushd时,通常将cd调用替换为它:

  1. if(…) and while(…) launch in a subshell. You do not need subshell here, it is faster to do these checks using just if … and while ….
  2. pushd . is not needed at all. While using pushd you normally replace the cd call with it:

pushd "$(dirname $SCRIPT_PATH)" >/dev/null
SCRIPT_PATH="$(pwd)"
popd >/dev/null

如果输出带有空格的内容,则

  • cd `…`将失败.目录可能包含空格.在上面的示例中,我使用"$(…)""`…`"也将起作用.
  • 您不需要在变量声明中尾随;.
  • readlink -f可以解析所有符号链接,因此您可以考虑将原始脚本缩减为SCRIPT_PATH="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))"(行为可能会发生变化,因为您的脚本似乎仅在最后一个组件中解析符号链接):这相当于${0:A:h}
  • if [ -h "$SCRIPT_PATH" ]是多余的,因为除非脚本路径是符号链接,否则不会执行具有相同条件的while正文.
  • readlink $SCRIPT_PATH将相对于包含$SCRIPT_PATH 的目录返回符号链接.因此,原始脚本可能无法用于解析最后一个组件中的符号链接.
  • if(…)then之间没有;.我很惊讶bash接受了这个.
  • cd `…` will fail if outputs something with spaces. It is possible for a directory to contain a space. In the above example I use "$(…)", "`…`" will also work.
  • You do not need trailing ; in variable declarations.
  • There is readlink -f that will resolve all symlinks thus you may consider reducing original script to SCRIPT_PATH="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))" (the behavior may change as your script seems to resolve symlinks only in last component): this is bash equivalent to ${0:A:h}.
  • if [ -h "$SCRIPT_PATH" ] is redundant since while body with the same condition will not be executed unless script path is a symlink.
  • readlink $SCRIPT_PATH will return symlink relative to the directory containing $SCRIPT_PATH. Thus original script cannot possibly used to resolve symlinks in last component.
  • There is no ; between if(…) and then. I am surprised bash accepts this.
  • 以上所有语句均适用于bash和zsh.

    All of the above statements apply both to bash and zsh.

    如果仅在最后一个组件中仅解析符号链接是必不可少的,则应这样编写:

    If resolving only symlinks only in last component is essential you should write it like this:

    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条语句,有以下示例:

    To illustrate 7th statement there is the following example:

    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时一样.
    1. Create directory $R/bash ($R is any directory, e.g. /tmp).
    2. Put your script there without modifications, e.g. under name $R/bash/script_path.bash. Add line echo "$SCRIPT_PATH" at the end of it and line #!/bin/bash at the start for testing.
    3. Make it executable: chmod +x $R/bash/script_path.bash.
    4. Create a symlink to it: cd $R/bash && ln -s script_path.bash link.
    5. cd $R
    6. Launch $R/bash/1. Now you will see that your script outputs $R while it should output $R/bash like it does when you launch $R/bash/script_path.bash.

    这篇关于bsh脚本获取脚本目录的zsh等效项是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆