【问题标题】:How to edit path variable in ZSH如何在 ZSH 中编辑路径变量
【发布时间】:2012-03-09 23:42:26
【问题描述】:

在我的 .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 语句的评估结果为假,即使对于明显存在的目录也是如此。

然后我删除了目录存在检查,$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

没有找到或执行底部目录中的程序。
我做错了什么?

【问题讨论】:

    标签: zsh


    【解决方案1】:

    仍然不确定问题出在哪里(可能是 $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)
    

    【讨论】:

      【解决方案2】:

      与其他 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 限定符来添加仅当元素存在时。请注意,您需要进行 globbing,因此 path+=/usr/local/mysql/bin(N) 不起作用。

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

      【讨论】:

      • +1 - 在zsh 中对$PATH 操作有用的另外两个快速提示(适用于路过的任何人):(1) 前置而不是附加:@987654340 @ 和 (2) 如果您使用 globbing 查找目录,则不必使用 for 循环,而只需执行 path+=( $PWD/node_modules/**/bin )(也适用于 ( 1)).
      • 谢谢,我使用了你的建议,path=($^path(N-/))。现在有没有办法确保每次运行 source ~/.zshrc 时相同的目录不会在 $PATH 中重复?谢谢
      • @unthought LOVE 你的 PRE-pend (foo[1,0]=bar) 诡计。 要爱默默无闻!
      【解决方案3】:

      你可以放

       setopt shwordsplit
      

      在您的.zshrc 中。然后 zsh 将像所有 Bourne shell 一样执行世界分割。默认值似乎是noshwordsplit 是一个错误功能,导致许多人挠头。如果这不是常见问题解答,我会感到惊讶。让我们看看......是的: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18 3.1:为什么 $var where var="foo bar" 没有达到我的预期?

      【讨论】:

        猜你喜欢
        • 2017-05-25
        • 1970-01-01
        • 2022-01-02
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 2018-04-04
        • 2019-10-18
        相关资源
        最近更新 更多