Question

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.

Was it helpful?

Solution

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}.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top