web-dev-qa-db-ja.com

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が設定されていません。

最初に、「if directory exists」関数内にechoステートメントを入れました。明確に存在するディレクトリであっても、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

下のディレクトリにあるプログラムはどれも、検出または実行されていませんでした。
何が悪いのですか?

22
Kevin Burke

他のシェルとは異なり、zshは変数の置換後にWordの分割またはグロビングを実行しません。したがって、_$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))
_

Nglob qualifier は、存在する一致のみを選択します。要素の1つがディレクトリまたはシンボリックリンク以外のものである可能性がある場合は、_-/_を修飾子リストに追加します(つまり、_(-/N)_または_(N-/)_)。壊れたシンボリックリンク)。 _^_ パラメータ展開フラグ は、グロブ修飾子が各配列要素に個別に適用されることを保証します。

N修飾子を使用して、要素が存在する場合にのみ要素を追加することもできます。グロビングが発生する必要があるため、path+=/usr/local/mysql/bin(N)は機能しないことに注意してください。

_path+=(/usr/local/bin/mysql/bin(N-/))
_

あなたは置くことができます

 setopt shwordsplit

あなたの.zshrc。次に、zshはすべてのBourneシェルが行うように世界分割を実行します。デフォルトがnoshwordsplitのように見えることは、多くの頭を引っかく原因となる誤機能です。 FAQじゃなかったらびっくりします。見てみましょう... yup: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l183.1:$ var where var = " foo bar "は私が期待することをしませんか?

5
Jens

それでも問題が何であるかわからない(おそらく$ 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
Kevin Burke