如何在ZSH中编辑路径变量

时间:2012-02-19 07:23:55

标签: zsh

在我的 .bash_profile 中,我有以下几行:

PATHDIRS="
/usr/local/mysql/bin
/usr/local/share/python
/opt/local/bin
/opt/local/sbin
$HOME/bin"
for dir in $PATHDIRS
do
    if [ -d $dir ]; then
        export PATH=$PATH:$dir
    fi
done

但是我尝试将其复制到 .zshrc ,并且未设置$PATH

首先我将echo语句放在“if directory exists”函数中,我发现if语句的计算结果为false,即使对于明显存在的目录也是如此。

然后我删除了目录存在检查,并且$PATH设置错误,如下所示:

/usr/bin:/bin:/usr/sbin:/sbin:
/usr/local/bin
/opt/local/bin
/opt/local/sbin
/Volumes/Xshare/kburke/bin
/usr/local/Cellar/ruby/1.9.2-p290/bin
/Users/kevin/.gem/ruby/1.8/bin
/Users/kevin/bin

找不到或执行底层目录中的任何程序 我做错了什么?

3 个答案:

答案 0 :(得分:48)

与其他shell不同,zsh在变量替换后不执行单词拆分或通配。因此$PATHDIRS扩展为包含变量值的单个字符串,而不是包含每个单独的以空格分隔的值的字符串列表。

使用数组是表达这一点的最佳方式(不仅在zsh中,而且在ksh和bash中)。

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

由于您以后可能不会引用pathdirs,所以您可以将其内联编写:

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

甚至有一种更短的表达方式:将您喜欢的所有目录添加到path数组中,然后选择存在的目录。

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

N glob qualifier仅选择存在的匹配项。如果您担心其中一个元素可能不是目录或符号链接,则将-/添加到限定符列表(即(-/N)(N-/))(例如一个破碎的符号链接)。 ^ parameter expansion flag确保glob限定符分别应用于每个数组元素。

您也可以使用N限定符添加元素(如果存在)。请注意,您需要使用通配符,因此path+=/usr/local/mysql/bin(N)将无效。

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

答案 1 :(得分:5)

你可以把

 setopt shwordsplit

.zshrc中。然后zsh将像所有Bourne shell一样执行世界分裂。默认值似乎是noshwordsplit是一种误导,导致许多头部刮伤。如果它不是FAQ,我会感到惊讶。让我们看看...是的: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18 3.1:为什么$ var其中var =“foo bar”不符合我的预期?

答案 2 :(得分:2)

仍然不确定问题是什么(也许是$ PATHDIRS中的新行)?但更改为zsh数组语法修复了它:

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)

path=($path $dir)