2012-02-19 10 views
21

En mis .bash_profile Tengo las siguientes líneas:cómo editar variable de ruta en 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 

Sin embargo he intentado copiar esto a mi .zshrc, y no se está estableciendo la $PATH.

Primero puse echo declaraciones dentro de la función "si el directorio existe" y encontré que la instrucción if se evaluaba como falsa, incluso para directorios que claramente existían.

Luego retira el directorio existe cheque y el $PATH se ajuste incorrecto de la siguiente manera:

/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 

Ninguno de los programas en los directorios inferiores estaban siendo encontrado o ejecutados.
¿Qué estoy haciendo mal?

Respuesta

48

A diferencia de otras conchas, zsh no realiza la división de palabras o comodines después de la sustitución de variables. Por lo tanto, $PATHDIRS se expande a una sola cadena que contiene exactamente el valor de la variable, y no a una lista de cadenas que contiene cada parte separada del espacio delimitada en blanco.

Usar una matriz es la mejor manera de expresar esto (no solo en zsh, sino también en ksh y bash).

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

Ya que probablemente no se va a hacer referencia a pathdirs más tarde, que también podría escribirlo en línea:

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

Incluso hay un camino más corto para expresar esto: poner todos los directorios que le gustan a la matriz path, luego seleccione las que existen.

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

El Nglob qualifier Buscamos solamente las coincidencias que existen. Agregue -/ a la lista de calificadores (es decir, (-/N) o (N-/)) si le preocupa que uno de los elementos sea algo más que un directorio o un enlace simbólico a uno (por ejemplo, un enlace simbólico roto). El ^parameter expansion flag asegura que el calificador glob se aplica a cada elemento de la matriz por separado.

También puede usar el calificador N para agregar un elemento solo si existe. Tenga en cuenta que necesita que ocurra el engomado, por lo que path+=/usr/local/mysql/bin(N) no funcionaría.

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

+1 - Dos consejos rápidos adicionales útiles para la manipulación '$ PATH' en' zsh' (para quien pasa): * (1) * para anteponer en lugar de append: 'ruta [1,0] =/ruta/to/dir', y * (2) * si está usando globbing para encontrar los directorios, no tiene que usar un ciclo for y en su lugar simplemente haga 'path + = ($ PWD/node_modules/**/bin ') (también funciona con * (1) *). – unthought

+0

Gracias, utilicé su sugerencia, con path = ($^path (N- /)). ¿Hay alguna forma de garantizar que los mismos directorios no se dupliquen en $ PATH cada vez que ejecuto source ~/.zshrc? Gracias – stansult

+2

@stansult [¿Hay alguna forma de agregar un directorio a mi PATH en zsh solo si no está presente?] (Http://unix.stackexchange.com/questions/62579/is-there-a-way- to-add-a-directory-to-my-path-in-zsh-only-if-its-not-already-pre) – Gilles

2

Todavía no estoy seguro de cuál era el problema (¿quizás nuevas líneas en $ PATHDIRS)? pero cambiando a la sintaxis de matrices zsh fija que:

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) 

y

path=($path $dir) 
5

Usted puede poner

setopt shwordsplit 

en su .zshrc. Entonces zsh realizará la división mundial como lo hacen todas las conchas de Bourne.Que el valor predeterminado sea noshwordsplit es una falla que causa muchos arañazos en la cabeza. Me sorprendería si no fuera una pregunta frecuente. Veamos ... yup: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18 3.1: ¿Por qué $ var donde var = "foo bar" no hacen lo que espero?