[ACCEPTED]-How to edit path variable in ZSH-zsh

Accepted answer
Score: 49

Unlike other shells, zsh does not perform 23 word splitting or globbing after variable 22 substitution. Thus $PATHDIRS expands to a single 21 string containing exactly the value of the 20 variable, and not to a list of strings containing 19 each separate whitespace-delimited piece 18 of the value.

Using an array is the best 17 way to express this (not only in zsh, but 16 also in ksh and bash).

pathdirs=(
    /usr/local/mysql/bin
    …
    ~/bin
)
for dir in $pathdirs; do
    if [ -d $dir ]; then
        path+=$dir
    fi
done

Since you probably 15 aren't going to refer to pathdirs later, you might 14 as well write it inline:

for dir in \
  /usr/local/mysql/bin \
  … \
  ~/bin
; do
  if [[ -d $dir ]]; then path+=$dir; fi
done

There's even a shorter 13 way to express this: add all the directories 12 you like to the path array, then select the 11 ones that exist.

path+=/usr/local/mysql/bin
…
path=($^path(N))

The N glob qualifier selects only the matches 10 that exist. Add the -/ to the qualifier list 9 (i.e. (-/N) or (N-/)) if you're worried that one of 8 the elements may be something other than 7 a directory or a symbolic link to one (e.g. a 6 broken symlink). The ^ parameter expansion flag ensures that the 5 glob qualifier applies to each array element 4 separately.

You can also use the N qualifier 3 to add an element only if it exists. Note 2 that you need globbing to happen, so path+=/usr/local/mysql/bin(N) wouldn't 1 work.

path+=(/usr/local/bin/mysql/bin(N-/))
Score: 5

You can put

 setopt shwordsplit

in your .zshrc. Then zsh will perform 4 world splitting like all Bourne shells do. That 3 the default appears to be noshwordsplit is a misfeature 2 that causes many a head scratching. I'd 1 be surprised if it wasn't a FAQ. Lets see... yup: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18 3.1: Why does $var where var="foo bar" not do what I expect?

Score: 3

Still not sure what the problem was (maybe 2 newlines in $PATHDIRS)? but changing to 1 zsh array syntax fixed it:

PATHDIRS=(
/usr/local/mysql/bin
/usr/local/share/python
/usr/local/scala/scala-2.8.0.final/bin
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin
/opt/local/etc
/opt/local/bin
/opt/local/sbin
$HOME/.gem/ruby/1.8/bin
$HOME/bin)

and

path=($path $dir)

More Related questions