Me pregunto dónde hay que añadir una nueva ruta a la variable de entorno PATH
. Sé que esto se puede lograr mediante la edición de .bashrc
(por ejemplo), pero no está claro cómo hacerlo.
De esta manera:
lenguaje: bash -->
export PATH=~/opt/bin:$PATH
o esto?
export PATH=$PATH:~/opt/bin
PATH=$PATH:~/opt/bin
o
PATH=~/opt/bin:$PATH
dependiendo de si quiere añadir ~/opt/bin
al final (para que se busque después de todos los demás directorios, en caso de que haya un programa con el mismo nombre en varios directorios) o al principio (para que se busque antes de todos los demás directorios).
Puede añadir varias entradas al mismo tiempo. PATH=$PATH:~/opt/bin:~/opt/node/bin
o variaciones en el ordenamiento funcionan bien. No pongas export
al principio de la línea ya que tiene complicaciones adicionales (ver más abajo en "Notas sobre shells diferentes a bash").
Si su PATH
es construido por muchos componentes diferentes, podría terminar con entradas duplicadas. Consulta https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command y https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command para evitar añadir duplicados o eliminarlos.
Algunas distribuciones ponen automáticamente ~/bin
en su PATH si existe, por cierto.
Ponga la línea para modificar PATH
en ~/.profile
, o en ~/.bash_profile
si eso es lo que tiene.
Tenga en cuenta que ~/.bash_rc
no es leído por ningún programa, y que ~/.bashrc
es el archivo de configuración de las instancias interactivas de bash. No debe definir variables de entorno en ~/.bashrc
. El lugar correcto para definir variables de entorno como PATH
es ~/.profile
(o ~/.bash_profile
si no le interesan otros shells que no sean bash). Ver ¿Cuál es la diferencia entre ellos y cuál debo usar?
No lo ponga en /etc/environment
o ~/.pam_environment
: estos no son archivos de shell, no puede usar sustituciones como $PATH
en ellos. En estos archivos, sólo puede anular una variable, no añadirla.
No necesitas exportar
si la variable ya está en el entorno: cualquier cambio del valor de la variable se refleja en el entorno.¹ PATH
está casi siempre en el entorno; todos los sistemas unix lo establecen muy pronto (normalmente en el primer proceso, de hecho).
En el momento de iniciar la sesión, puede confiar en que PATH
ya está en el entorno, y ya contiene algunos directorios del sistema. Si estás escribiendo un script que puede ser ejecutado antes mientras se configura algún tipo de entorno virtual, puedes necesitar asegurarte de que PATH
no esté vacío y sea exportado: si PATH
aún no está configurado, entonces algo como PATH=$PATH:/alguna/directorio
establecería PATH
a :/alguna/directorio
, y el componente vacío al principio significa el directorio actual (como .:/alguna/directorio
).
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
En bash, ksh y zsh, exportar
es una sintaxis especial, y tanto PATH=~/opt/bin:$PATH
como exportar PATH=~/opt/bin:$PATH
hacen lo correcto incluso. En otros shells estilo Bourne/POSIX como dash (que es /bin/sh
en muchos sistemas), export
se analiza como un comando ordinario, lo que implica dos diferencias:
~
sólo se analiza al principio de una palabra, excepto en las asignaciones (véase https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command/25704#25704 para más detalles);$PATH
fuera de las comillas dobles [se rompe si PATH
contiene espacios en blanco o \[*?
](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters).Así, en shells como dash, establece exportar PATH=~/opt/bin:$PATH
PATH
a la cadena literal ~/opt/bin/:
seguida del valor de PATH
hasta el primer espacio.
PATH=~/opt/bin:$PATH
(una asignación desnuda) no requiere comillas y hace lo correcto. Si quiere usar exportar
en un script portable, necesita escribir exportar PATH="$HOME/opt/bin:$PATH"
, o PATH=~/opt/bin:$PATH; exportar PATH
(o PATH=$HOME/opt/bin:$PATH; exportar PATH
para la portabilidad incluso al shell Bourne que no aceptaba exportar var=value
y no hacía expansión de tilde).
Esto no era cierto en los shells Bourne (como en el verdadero shell Bourne, no en los shells modernos estilo POSIX), pero es muy poco probable que te encuentres con shells tan antiguos hoy en día;
Cualquiera de las dos formas funciona, pero no hacen lo mismo: los elementos de PATH
se comprueban de izquierda a derecha. En tu primer ejemplo, los ejecutables en ~/opt/bin
tendrán prioridad sobre los instalados, por ejemplo, en /usr/bin
, lo que puede ser o no lo que quieres.
En particular, desde el punto de vista de la seguridad, es peligroso añadir rutas al frente, porque si alguien puede obtener acceso de escritura a tu ~/opt/bin
, puede poner, por ejemplo, un ls
diferente allí, que entonces probablemente usarías en lugar de /bin/ls
sin darte cuenta. Ahora imagina lo mismo para ssh
o tu navegador o tu elección... (Lo mismo ocurre con la colocación de . en su ruta).
Me confunde la pregunta 2 (ya eliminada de la pregunta por tratarse de un tema no relacionado):
¿Qué's una forma viable de añadir más rutas en diferentes líneas? Inicialmente pensé que esto podría hacer el truco:
export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin
pero no lo hace'porque la segunda asignación no' sólo anexa
~/opt/node/bin
, sino también todo elPATH
previamente asignado.Esta es una posible solución:
export PATH=$PATH:~/opt/bin:~/opt/node/bin
pero para la legibilidad yo' preferiría tener una asignación para una ruta.
Si dices
PATH=~/opt/bin
eso'es todo lo que estará en su PATH. PATH es sólo una variable de entorno, y si quieres añadir algo al PATH, tienes que reconstruir la variable con exactamente el contenido que quieres. Es decir, lo que das como ejemplo a la pregunta 2 es exactamente lo que quieres hacer, a no ser que me esté perdiendo totalmente el sentido de la pregunta.
Yo uso ambas formas en mi código. Tengo un perfil genérico que instalo en todas las máquinas en las que trabajo y que tiene este aspecto, para dar cabida a los directorios que puedan faltar:
export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
if [ -d $bindir ]; then
PATH=$PATH:${bindir}
fi
done