我想翻译这个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
Run Code Online (Sandbox Code Playgroud)
我已经知道的是,我可以
SCRIPT_PATH="$0";用来获取脚本所在的路径.但后来我的"readlink"语句出错了.
谢谢你的帮助
除了BASH_SOURCE我看不到你需要做的任何改变.但脚本的目的是什么?如果你想获得你的脚本所在的目录${0:A:h}(:A将解析所有符号链接,:h将截断最后一个路径组件,留下你的目录名称):
SCRIPT_PATH="${0:A:h}"
Run Code Online (Sandbox Code Playgroud)
就这样.请注意,原始脚本有一些奇怪的事情:
if(…)并在子shell中while(…)启动….你不需要在这里使用子shell,只需使用if …和更快地执行这些检查while ….pushd .根本不需要.使用pushd时通常cd用它替换呼叫:
pushd "$(dirname $SCRIPT_PATH)" >/dev/null
SCRIPT_PATH="$(pwd)"
popd >/dev/null
Run Code Online (Sandbox Code Playgroud)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接受这个.以上所有语句都适用于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
Run Code Online (Sandbox Code Playgroud)
.
为了说明第7个陈述,有以下示例:
$R/bash($R例如,任何目录/tmp).$R/bash/script_path.bash.echo "$SCRIPT_PATH"在它的末尾添加行并#!/bin/bash在开始时行以进行测试.chmod +x $R/bash/script_path.bash.cd $R/bash && ln -s script_path.bash link.cd $R$R/bash/1.现在,您将看到您的脚本输出,$R而它应该$R/bash像您启动时一样输出$R/bash/script_path.bash.