2012-02-19 24 views
21

Trong .bash_profile tôi có các dòng sau của tôi:Làm thế nào để chỉnh sửa biến đường dẫn trong ZSH

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 

Tuy nhiên tôi cố gắng sao chép này để tôi zshrc, và $PATH không được thiết lập.

Trước tiên, tôi đặt các câu lệnh echo bên trong hàm "nếu thư mục tồn tại" và tôi thấy rằng câu lệnh if được đánh giá là sai, ngay cả đối với các thư mục đã tồn tại rõ ràng.

Sau đó, tôi loại bỏ các thư mục-tồn tại kiểm tra, và $PATH đã được đặt không chính xác như thế này:

/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 

Không ai trong số các chương trình trong thư mục phía dưới đã được tìm thấy hoặc thực thi.
Tôi đang làm gì sai?

Trả lời

48

Không giống như vỏ khác, zsh không thực hiện tách từ hoặc globbing sau khi thay biến. Do đó, $PATHDIRS mở rộng thành một chuỗi chứa chính xác giá trị của biến và không chứa danh sách các chuỗi chứa từng phần riêng biệt của giá trị được phân cách bằng dấu cách.

Sử dụng mảng là cách tốt nhất để thể hiện điều này (không chỉ trong zsh, mà còn trong ksh và bash).

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

Vì bạn có thể sẽ không tham khảo pathdirs sau, bạn cũng có thể viết nó inline:

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

Thậm chí còn có một cách ngắn hơn để bày tỏ điều này: thêm tất cả các thư mục mà bạn thích đến mảng path, sau đó chọn mảng tồn tại.

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

Nglob qualifier chỉ chọn các kết quả phù hợp tồn tại. Thêm -/ vào danh sách định danh (ví dụ: (-/N) hoặc (N-/)) nếu bạn lo lắng rằng một trong các thành phần có thể là một thứ khác với thư mục hoặc liên kết tượng trưng đến một thư mục (ví dụ: liên kết tượng trưng bị hỏng). ^parameter expansion flag đảm bảo rằng vòng loại glob áp dụng riêng cho từng phần tử mảng.

Bạn cũng có thể sử dụng mã định danh N để chỉ thêm phần tử nếu nó tồn tại. Lưu ý rằng bạn cần globbing để xảy ra, vì vậy path+=/usr/local/mysql/bin(N) sẽ không hoạt động.

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

+1 - Hai mẹo nhanh bổ sung hữu ích cho thao tác '$ PATH' trong' zsh' (đối với bất kỳ ai đi qua): * (1) * để thêm vào thay vì nối thêm: 'path [1,0] =/path/to/dir', và * (2) * nếu bạn đang sử dụng globbing để tìm các thư mục, bạn không phải sử dụng vòng lặp for và thay vào đó chỉ cần thực hiện 'path + = ($ PWD/node_modules/**/bin ') (cũng hoạt động với * (1) *). – unthought

+0

Cảm ơn, tôi đã sử dụng đề xuất của bạn, với đường dẫn = ($^đường dẫn (N- /)). Bây giờ là có một cách để đảm bảo rằng cùng một thư mục không trùng lặp trong $ PATH mỗi khi tôi chạy nguồn ~/.zshrc? Cảm ơn – stansult

+2

@stansult [Có cách nào để thêm thư mục vào PATH của tôi trong zsh chỉ khi nó chưa có?] (Http://unix.stackexchange.com/questions/62579/is-there-a-way- to-add-a-directory-to-my-path-in-zsh-only-nếu-nó-không-đã-trước) – Gilles

2

Vẫn không chắc chắn vấn đề là gì (có thể là dòng mới trong $ PATHDIRS)? nhưng thay đổi cú pháp mảng zsh cố định nó:

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) 
5

Bạn có thể đặt

setopt shwordsplit 

trong .zshrc của bạn. Sau đó, zsh sẽ thực hiện tách thế giới giống như tất cả các shell Bourne làm.Rằng mặc định có vẻ là noshwordsplit là một sự không hài lòng khiến nhiều đầu bị trầy xước. Tôi sẽ ngạc nhiên nếu nó không phải là một câu hỏi thường gặp. Cho phép xem ... yup: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18 3.1: Tại sao $ var trong đó var = "foo bar" không làm những gì tôi mong đợi?

Các vấn đề liên quan