在我的 .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
找不到或执行底层目录中的任何程序 我做错了什么?
答案 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)