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:
SCRIPT_PATH=\
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:
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 …
.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 `…`
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.;
in variable declarations.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.;
between if(…)
and then
. I am surprised bash accepts this.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
.
To illustrate 7th statement there is the following example:
$R/bash
($R
is any directory, e.g. /tmp
).$R/bash/script_path.bash
. Add line echo "$SCRIPT_PATH"
at the end of it and line #!/bin/bash
at the start for testing.chmod +x $R/bash/script_path.bash
.cd $R/bash && ln -s script_path.bash link
.cd $R
$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
.