it-swarm-es.tech

¿Cómo agregar correctamente una ruta a PATH?

Me pregunto dónde se debe agregar una nueva ruta a la variable de entorno PATH. Sé que esto se puede lograr editando .bashrc (por ejemplo), pero no está claro cómo hacerlo.

De esta manera:

export PATH=~/opt/bin:$PATH

¿o esto?

export PATH=$PATH:~/opt/bin
994
Paolo

Las cosas simples

PATH=$PATH:~/opt/bin

o

PATH=~/opt/bin:$PATH

dependiendo de si desea agregar ~/opt/bin al final (para buscar todos los demás directorios, en caso de que haya un programa con el mismo nombre en varios directorios) o al principio (para buscar antes de todos los demás directorios).

Puede agregar varias entradas al mismo tiempo. PATH=$PATH:~/opt/bin:~/opt/node/bin o variaciones en el orden funcionan bien. No coloque export al comienzo de la línea, ya que tiene complicaciones adicionales (ver más abajo en "Notas sobre los depósitos que no sean bash").

Si su PATH es construido por muchos componentes diferentes, puede terminar con entradas duplicadas. Consulte ¿Cómo agregar la ruta del directorio personal para que Unix descubra qué comando? y Eliminar entradas duplicadas de $ PATH con el comando awk para evitar agregar duplicados o eliminarlos.

Algunas distribuciones ponen automáticamente ~/bin en su RUTA si existe, por cierto.

Donde ponerlo

Ponga la línea para modificar PATH en ~/.profile, o en ~/.bash_profile si eso es lo que tienes.

Tenga en cuenta que ~/.bash_rc no es leído por ningún programa, y ​​~/.bashrc es el archivo de configuración de 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 te importan las conchas que no sean bash). Ver ¿Cuál es la diferencia entre ellos y cuál debo usar?

No lo pongas en /etc/environment o ~/.pam_environment: estos no son archivos Shell, no puedes usar sustituciones como $PATH ahí. En estos archivos, solo puede anular una variable, no agregarla.

Posibles complicaciones en algunos scripts del sistema

No necesita export si la variable ya está en el entorno: cualquier cambio en el valor de la variable se refleja en el entorno.¹ PATH está casi siempre en el entorno; todos los sistemas unix lo configuraron desde el principio (de hecho, generalmente en el primer proceso).

En el momento de iniciar sesión, puede confiar en que PATH ya está en el entorno y contiene algunos directorios del sistema. Si está escribiendo una secuencia de comandos que puede ejecutarse antes mientras configura algún tipo de entorno virtual, es posible que deba asegurarse de que PATH no esté vacío y se exporte: si PATH aún no está configurado , entonces algo como PATH=$PATH:/some/directory establecería PATH en :/some/directory, y el componente vacío al principio significa el directorio actual (como .:/some/directory).

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi

Notas sobre conchas que no sean bash

En bash, ksh y zsh, export es una sintaxis especial, y ambas PATH=~/opt/bin:$PATH y export PATH=~/opt/bin:$PATH hacer lo correcto incluso. En otros shells de estilo Bourne/POSIX como el guión (que es /bin/sh en muchos sistemas), export se analiza como un comando ordinario, lo que implica dos diferencias:

Entonces en conchas como guiones, export PATH=~/opt/bin:$PATH establece PATH en la cadena literal ~/opt/bin/: seguido del valor de PATH hasta el primer espacio. PATH=~/opt/bin:$PATH (una tarea básica) no requiere comillas y hace lo correcto. Si desea utilizar export en un script portátil, debe escribir export PATH="$HOME/opt/bin:$PATH" o PATH=~/opt/bin:$PATH; export PATH (o PATH=$HOME/opt/bin:$PATH; export PATH para portabilidad incluso para el Bourne Shell que no aceptó export var=value y no hice tilde expansión).

¹ Esto no era cierto en los shells Bourne (como en el Bourne Shell real, no en los shells modernos de estilo POSIX), pero es muy poco probable que encuentre estos shells viejos en estos días.

De cualquier manera funciona, pero no hacen lo mismo: los elementos de PATH se verifican de izquierda a derecha. En su primer ejemplo, ejecutables en ~/opt/bin tendrá prioridad sobre los instalados, por ejemplo, en /usr/bin, que puede o no ser lo que quieres.

En particular, desde un punto de vista de seguridad, es peligroso agregar rutas al frente, porque si alguien puede obtener acceso de escritura a su ~/opt/bin, pueden poner, por ejemplo, un ls diferente allí, que probablemente usarías en lugar de /bin/ls sin darse cuenta. Ahora imagine lo mismo para ssh o para su navegador o elección ... (Lo mismo se triplica para ponerlo en su camino).

88
Ulrich Schwarz

Estoy confundido con la pregunta 2 (ya que se eliminó de la pregunta porque se debió a un problema no relacionado):

¿Cuál es una forma viable de agregar 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 solo agrega ~/opt/node/bin, pero también todo el PATH asignado previamente.

Esta es una posible solución alternativa:

export PATH=$PATH:~/opt/bin:~/opt/node/bin

pero para facilitar la lectura, preferiría tener una asignación para una ruta.

Si usted dice

PATH=~/opt/bin

eso es todos que estará en su RUTA. RUTA es solo una variable de entorno, y si desea agregar a la RUTA, debe reconstruir la variable con exactamente el contenido que desea. Es decir, lo que da como ejemplo a la pregunta 2 es exactamente lo que quiere hacer, a menos que me esté perdiendo totalmente el punto de la pregunta.

Yo uso ambos formularios en mi código. Tengo un perfil genérico que instalo en cada máquina en la que trabajo que se ve así, para acomodar directorios que pueden 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
39
Carl Cravens

Linux determina la ruta de búsqueda ejecutable con $PATH Variable ambiental. Para agregar directorio/datos/myscripts al comienzo de $PATH variable de entorno, use lo siguiente:

PATH=/data/myscripts:$PATH

Para agregar ese directorio al final de la ruta, use el siguiente comando:

PATH=$PATH:/data/myscripts

Pero lo anterior no es suficiente porque cuando establece una variable de entorno dentro de un script, ese cambio es efectivo solo dentro del script. Solo hay dos formas de evitar esta limitación:

  • Si dentro de la secuencia de comandos, exporta la variable de entorno, es efectiva dentro de cualquier programa llamado por la secuencia de comandos. Tenga en cuenta que no es efectivo dentro del programa que llamó al script.
  • Si el programa que llama al script lo hace mediante inclusión en lugar de llamar, cualquier cambio de entorno en el script es efectivo dentro del programa de llamada. Dicha inclusión se puede hacer con el comando punto o el comando fuente.

Ejemplos:

$HOME/myscript.sh
source $HOME/myscript.sh

La inclusión básicamente incorpora el guión "llamado" en el guión "llamado". Es como un #include en C. Por lo tanto, es efectivo dentro del script o programa "llamado". Pero, por supuesto, no es efectivo en ningún programa o script llamado por el programa de llamada. Para que sea efectivo en toda la cadena de llamadas, debe seguir la configuración de la variable de entorno con un comando de exportación.

Como ejemplo, el programa bash Shell incorpora los contenidos del archivo .bash_profile por inclusión. Coloque las siguientes 2 líneas en .bash_profile:

PATH=$PATH:/data/myscripts
export PATH

efectivamente coloca esas 2 líneas de código en el programa bash. Entonces, dentro de bash, la variable $ PATH incluye $HOME/myscript.sh, y debido a la declaración de exportación, cualquier programa llamado por bash tiene la alteración $PATH variable. Y debido a que cualquier programa que ejecute desde un indicador de bash se llama mediante bash, la nueva ruta está en vigor para todo lo que ejecute desde el indicador de bash.

La conclusión es que para agregar un nuevo directorio a la ruta, debe agregar o anteponer el directorio a la variable de entorno $ PATH dentro de un script incluido en el Shell, y debe exportar el $PATH Variable ambiental.

Más información aquí

25
Steve Brown

Desde hace algún tiempo he guardado conmigo dos funciones pathadd y pathrm que ayudan a agregar elementos a la ruta sin la necesidad de preocuparse por las duplicaciones.

pathadd toma un argumento de ruta única y un argumento opcional after que, si se proporciona, se agregará al PATH de lo contrario lo antepone.

En casi todas las situaciones, si está agregando a la ruta, es probable que desee anular cualquier cosa que ya esté en la ruta, por lo que opto por anteponer por defecto.

pathadd() {
    newelement=${1%/}
    if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "$2" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}

Ponga esto en cualquier script que desee alterar el entorno PATH y ahora puede hacerlo.

pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH

Le garantizamos que no agregará a la ruta si ya está allí. Si ahora quieres asegurarte /baz/bat está al comienzo.

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH

Ahora cualquier camino se puede mover al frente si ya está en el camino sin duplicarlo.

20
Brett Ryan

No puedo hablar por otras distribuciones, pero Ubuntu tiene un archivo,/etc/environment, que es la ruta de búsqueda predeterminada para todos los usuarios. Como mi computadora solo la uso yo, pongo los directorios que quiero en mi camino allí, a menos que sea una adición temporal que coloque en un script.

10
Jim Bradley

Hay algunas situaciones en las que se usa PATH=/a/b:$PATH podría considerarse la forma "incorrecta" de agregar una ruta a PATH:

  1. Agregar una ruta que en realidad no es un directorio.
  2. Agregar una ruta que ya está en PATH en la misma forma.
  3. Agregar una ruta relativa (ya que el directorio real buscado cambiaría a medida que cambia el directorio de trabajo actual).
  4. Agregar una ruta que ya está en PATH en una forma diferente (es decir, un alias debido al uso de enlaces simbólicos o ..).
  5. Si evita hacer 4, no mueve la ruta al frente de PATH cuando se pretende anular otras entradas en PATH.

Esta función (solo Bash) hace lo "correcto" en las situaciones anteriores (con una excepción, ver más abajo), devuelve códigos de error e imprime mensajes de Niza para humanos. Los códigos y mensajes de error se pueden deshabilitar cuando no se desean.

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "$1" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
    dir="$(command cd "$1"; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}

La excepción es que esta función no canoniza las rutas agregadas a PATH por otros medios, por lo que si un alias no canónico para una ruta está en PATH, esto agregará un duplicado. Intentar canonizar rutas que ya están en PATH es una propuesta incierta ya que una ruta relativa tiene un significado obvio cuando se pasa a prepath pero cuando ya está en la ruta no sabes cuál era el directorio de trabajo actual cuando fue agregado.

7
cjs

Para agregar una nueva ruta a la variable de entorno PATH:

export PATH=$PATH:/new-path/

Para que este cambio se aplique a cada Shell que abra, agréguelo al archivo que el Shell fuente cuando se invoca. En diferentes shells esto puede ser:

  • Bash Shell: ~/.bash_profile, ~/.bashrc o perfil
  • Korn Shell: ~/.kshrc o .profile
  • Z Shell: ~/.zshrc o .zprofile

p.ej.

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

Puede ver la ruta proporcionada en la salida anterior.

7
Amit24x7

Para mí (en Mac OS X 10.9.5), agregar el nombre de la ruta (por ejemplo, /mypathname) al archivo /etc/paths funcionó muy bien.

Antes de editar, echo $PATH devoluciones:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Después de editar /etc/paths y reiniciando el Shell, la variable $ PATH se agrega con /pathname. En efecto, echo $PATH devoluciones:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

Lo que pasó es que /mypathname se ha agregado al $PATH variable.

6
faelx

Aquí está mi solución:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

Un buen y sencillo revestimiento que no deja un rastro :

5
AJ.