¿Cómo se calcula exactamente PATH?

He leído una docena de respuestas diferentes y he hablado con muchas personas y tengo dificultades para entender cómo se calcula PATH en diferentes escenarios. Específicamente estoy pensando en

  1. ¿Cómo se calcula exactamente PATH para bash?
  2. ¿Cómo se calcula exactamente para otros proyectiles? (Supongo que depende del caparazón, pero ¿cuál es el punto en común entre todos los caparazones?)
  3. ¿Cómo se calcula exactamente para las aplicaciones GUI?
  4. ¿Me estoy perdiendo otra forma de lanzar cosas? ¿Los demonios hacen algo diferente? (¿No lo creo? Pero tal vez...)

Además, ahora estoy en High Sierra, pero veo que algunas personas mencionaron que esto cambió en algún momento.

He visto esta respuesta y esta , pero ambas parecen estar enfocadas explícitamente en lo que sucede dentro de bash.

¿Qué quiere decir con la frase, "¿cómo se calcula PATH ?. Es una variable de entorno que se establece
@Allan sí, pero ¿cómo se configura exactamente? No es solo, .bash_profilepor ejemplo, porque en el momento en que se ejecuta, PATH ya tiene cosas (es por eso que agregamos al frente o al final). Se calcula considerando alguna secuencia de fuentes y ejecutando alguna secuencia de scripts, pero ¿ cuáles son esos ?
Voto para cerrar esta pregunta como demasiado amplia. Edite la pregunta para limitarla a un problema específico con suficientes detalles para identificar una respuesta adecuada. Evite hacer varias preguntas distintas a la vez.
@ user3439894 ¿Recomendaría hacer cada uno de estos como una pregunta separada? Porque parece que sería una gran cantidad de superposición y es probable que algunas de las respuestas sean idénticas.
De hecho, es una pregunta muy amplia. Pero aquí hay algunos consejos: bash y otros shells de estilo bourne, y también csh y shells relacionados, se utilizarían path_helperpara ayudar a establecer la variable PATH. Echa un vistazo a su página de manual; encontrará que leen /etc/pathsy /etc/paths.d/*por los contenidos. Se aconseja a los usuarios de otros shells que adapten este método; de esa manera, todos los shells obtienen la misma RUTA.

Respuestas (3)

Voy a agrupar 1 y 2 porque todos los shells leen archivos al inicio.

PATH se hereda de su proceso padre. Este es un concepto clave que debe comprender.

El PATH primero está codificado en el kernel:

sysctl user.cs_path
user.cs_path: /usr/bin:/bin:/usr/sbin:/sbin

launchd que actúa como initpuede configurarse para cambiar esta RUTA. Generalmente no se cambia.

El loginwindow.app configurará un entorno cuando inicie sesión en su computadora. Se verificará que PATH se haya establecido o se establecerá en la ruta codificada en el kernel o en una ruta modificada establecida por launchd. Es como si loginwindow.app estuviera llamando login -pf <username>.

En este punto, un usuario LaunchAgent o LaunchDaemon puede modificar la RUTA.

Esta será la RUTA disponible para las aplicaciones GUI desde el Finder. (Las primeras versiones de OS X podían usar ~/.MacOSX/environment.plist para cambiar la RUTA de las aplicaciones GUI). Ahora bien, si esto parece complicado, no lo es y más que probable, como yo, el PATH disponible es/usr/bin:/bin:/usr/sbin:/sbin

Cuando inicia Terminal.app, primero llama login(login -pf ), lo que activa su shell para que se trate como un shell de inicio de sesión. Se leen los archivos apropiados en /etc y su carpeta HOME. Ahora, la RUTA debe ser diferente a la establecida por loginwindow.app. ¿Recuerdas que hablamos de la herencia? Si inicia una aplicación GUI desde su sesión de terminal, la RUTA disponible para la aplicación GUI será la misma que la establecida por el shell.

En cuanto a los demonios, normalmente se inician por su ruta absoluta.

¡Gracias por explicar cómo launchd encaja en todo esto! ¡Nadie más podría decirme!
Launched es solo otro proceso y funciona como todos los demás. Hereda un entorno y establece un entorno para los procesos que bifurca.

Desde la página man para PATH ( man path):

La ruta de búsqueda de comandos. Es una lista de directorios separados por dos puntos en los que el shell busca comandos (consulte EJECUCIÓN DE COMANDOS a continuación).... La ruta predeterminada depende del sistema y la establece el administrador que instala bash. Un valor común es ``/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin''.

Entonces, a partir de eso, excepto de la página de manual de bash, vemos que la ruta de bash es (inicialmente):

  • dependiente del sistema y no dependiente del shell
  • establecido por quien instaló bash (en este caso Apple)
  • tiene un valor por defecto

La ruta puede (obviamente) ser modificada. Hay varios lugares donde se puede establecer la variable de entorno PATH:

  • ~/.bashrc
  • ~/.bash_profile

En macOS, el archivo /etc/pathsse usa para configurar las rutas de búsqueda:

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

Además, la ruta es configurada inicialmente por la /usr/libexec/path_helperutilidad que crea una ruta basada en el contenido de/etc/paths.d

Se llama desde /etc/profileel cual establece el perfil bash de todo el sistema (los individuales se configuran en ~/.profile)

En cuanto a las aplicaciones GUI, la ruta del shell realmente no tiene ningún efecto. La única vez que una aplicación GUI (Cocoa, Quartz, Metal) tiene algo que ver con PATH es cuando abre un shell (ya sea interactivo o no interactivo). En ese momento, utilizará el entorno PATH tal como está establecido o realizará los cambios que necesite en tiempo de ejecución.

Diferentes conchas

Cada uno de los shells tiene un perfil diferente en todo el sistema (al igual que bash) que establece la RUTA inicial (llamando a la path_helperutilidad)

  • Zsh =/etc/zprofile
  • ksh =/etc/profile
  • dinero =/etc/csh.login
Sí, pero no todo se inicia a través de bash, ¿verdad? Si ejecuto eshell en emacs o korn shell, entonces no pasará por el mismo proceso. Me doy cuenta de que va a ser diferente por shell, pero ¿es completamente diferente o el sistema operativo proporciona una "base común de inicialización"? ¿Qué pasa con las aplicaciones lanzadas a través de Spotlight? ¿Cómo se calcula el PATH que ven?
La terminología es importante: la ruta no se calcula. Está puesto. Estás confundiendo OS con Shell. Un shell no es más que un entorno para ejecutar comandos en un sistema operativo.
Muy bien, Allan, aunque no estoy seguro de qué otro término usar. De hecho, la ruta está establecida (desde el punto de vista de los scripts), pero desde el punto de vista de una aplicación que podría usar la RUTA, hubo una serie de pasos que se realizaron para producir la variable de entorno PATH actual. En cuanto a las aplicaciones GUI, no usar la RUTA es diferente a que no esté disponible. Puedes hacer system attribute PATHo algo en AppleScript, ¿verdad? El valor que veo allí... ¿de dónde viene? ¿Qué serie de pasos siguió el sistema operativo para configurarlo?
Esto suena cada vez más como si tuviera un problema XY . ¿Cuál es el problema con el que te encuentras porque AppleScript no necesita tener una ruta de shell configurada?
Un poco ... Realmente no tengo un problema (bueno, lo tengo, y su pyenv no se instala correctamente, pero puedo darme cuenta de eso con una comprensión básica), estoy buscando una comprensión más profunda de cómo funciona esto, no para soluciones a nada concreto.
Es por eso que está marcado (no lo he hecho) como demasiado amplio. Lo primero que le pediría que consulte es el Manual de referencia de Bash , que le brindará una buena introducción sobre cómo funciona esto.
Jaja, lo entiendo y agradezco el intento de responderlo. El proceso bash sobre cómo se construye PATH es en realidad la parte que menos me interesa, ya que está razonablemente bien documentada como usted dice. Son las otras cosas (como lo que verán las aplicaciones GUI o lo que verá mi perfil de eshell) lo que me confunde

Todos: comprendan que Apple ha cambiado el paradigma de rutas con el tiempo en Sierra (consulte https://lluad.com/blog/os-x-system-path/ ), HighSierra y Mojave. Path_helper ahora funciona de manera algo diferente, parece porque me ha bloqueado las ventanas de la terminal que puedo liberar y funciona bien comentando

# if [ -x /usr/libexec/path_helper ]; then
#   eval `/usr/libexec/path_helper -s`
#  fi

en /etc/profile.

Tengo secuencias de comandos que corrigen la ruta porque tengo varias herramientas funcionando (el núcleo de ellas está instalado por Homebrew, pero eso es solo alrededor de 15 de las 25 que uso todos los días) y estas deben configurarse para su uso en .app aplicaciones, en inicios de secuencias de comandos .sh y para inicio automático en secuencia de inicio protegida en Mojave. Es confuso, pero seguro que Mojave ha cambiado la estructura requerida y necesito mejorarla yo mismo.

Lo que esto significa para esta pregunta en particular es que la pregunta es pertinente en toda su amplitud y que debe ser respondida por desarrolladores que sintieron el dolor y arreglaron sus sistemas para Mojave, y también provienen de varios "mundos" como los IDE normales. , XCode, Eclipse, Bean, Intellij, etc. También, aquellos que dependen de homebrew stacks, o mamp stacks, etc. Y para aquellos que están trabajando con docker, .node, vm, etc., y otras herramientas más profundas. A medida que Apple implemente una mayor seguridad, nuestras cosas se estropearán, pero me alegro de que Apple esté haciendo su trabajo. Necesitamos hacer lo nuestro, por lo que necesitamos gente de vanguardia para transmitir la nueva sabiduría. Los artículos que tienen 6 meses o más nos van a confundir.

De alguna manera, esto no parece responder a la pregunta anterior. Si la respuesta está en la página que vinculó, resúmala directamente en su publicación (y tal vez acorte los párrafos posteriores). Además, no solo menciones que haces las cosas de manera diferente, sino que también expliques/muestres cómo lo haces.