I'm having trouble during parameter expansion in zsh: It's enclosing my variable in quotes.
Here is my script. (Apologies for the noise, the only real important line is the last one with the find
call, but I wanted to make sure I'm not hiding details of my code)
#broken_links [-r|--recursive] [<path>]
# find links whose targets don't exist and print them. If <path> is given, look
# at that path for the links. Otherwise, the current directory is used is used.
# If --recursive is specified, look recursively through path.
broken_links () {
recurse=
search_path=$(pwd)
while test $# != 0
do
case "$1" in
-r|--recursive)
recurse=t
;;
*)
if test -d "$1"
then
search_path="$1"
else
echo "$1 not a valid path or option"
return 1
fi
;;
esac
shift
done
find $search_path ${recurse:--maxdepth 1} -type l ! -exec test -e {} \; -print
}
Just to be clear, in the find
line, I'd like this: if recurse
is null, substitute -maxdepth 1
. If recurse
is set to t
, substitute nothing (i.e. let find do it's normal recursive behavior).
It may be kind of weird to look at because, although this is just the ${name:-word}
form, word
actually starts with a hyphen. (See more about this here http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion)
Instead, what's happening is, if recurse
is null, it substitutes "-maxdepth 1"
(note the surrounding quotes) and if recurse
is set, it's substituting ""
.
The exact error when not recursing is find: unknown predicate `-maxdepth 1'
. You can try this for yourself by just saying find "-maxdepth 1"
for example. When we do want recursion, something odd is happening I can't quite explain, but the error is find `t': No such file or directory
.
Does anyone know how to make zsh not place quotes in this parameter expansion? I believe that is my problem here.
Thanks.
zsh isn't actually adding quotes around that, it just isn't doing word
splitting on the results of the parameter expansion. This is how it's
documented to behave by default. From the zshexpn
man page near the
beginning of the parameter expansion section:
Note in particular the fact that words of unquoted parameters are not
automatically split on whitespace unless the option SH_WORD_SPLIT is set
So, you can either set that option by doing setopt sh_word_split
, causing
splitting to be done for all parameter expansions or you can explicitly request
it for just that expansion by using:
${=recurse:--maxdepth 1}
Note the =
sign as the first character inside the braces. This is also noted
in the zshexpn
man page, search for ${=spec}
.