En OSX Yosemite, ¿por qué puedo configurar muchas variables de entorno para aplicaciones GUI, pero no puedo configurar la variable específica PATH?

16

Después de haber resuelto los problemas de OSX 'PATH hasta el lanzamiento de Mavericks, ¡los problemas vuelven en Yosemite!

Por lo tanto, quiero imitar la launch.confcaracterística anterior en la nueva versión de Mac OSX 10.10 Yosemite, para tener la variable de entorno PATH en aplicaciones GUI como Carbon Emacs o RStudio disponibles. Usé la gran idea del usuario de stackoverflow ursa para configurar un script de shell que configura las variables de entorno a través de launchctl. (Consulte su respuesta de stackoverflow aquí .) Esto funciona para la mayoría de las variables de entorno, pero no para la variable PATH .

1. ¿Qué he hecho?

Primero escribí el /etc/environment.rcguión con el siguiente aspecto:

launchctl setenv PATH /Users/halloleo/bin:/usr/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv JAVA_HOME /usr/local/jdk1.7
launchctl setenv ENVIRONMENT_RC "yes"

Luego creé los plists para launchd(listados de estos y de otros scripts mencionados en el apéndice a continuación). Luego los activé con

$ sudo launchctrl load ...

Luego deshabilité la path_helperutilidad en el /etc/perfil del archivo de inicio de shell , para que no sobrescriba la environment.rcconfiguración. Y finalmente reinicié la máquina.

2. ¿Cuál es el efecto?

Cuando inicio Terminal, las nuevas variables de entorno JAVA_HOMEy ENVIRONMENT_RCse establecen de acuerdo con environment.rc, pero PATH se establece en

/ usr / bin: / bin

Para asegurarme, ningún basharchivo de inicio se interpuso en la forma en que escribí un pequeño script de Python en su lugar (también en el apéndice) para mostrar las variables en el entorno actual y lo ejecuto directamente haciendo doble clic en un contenedor Platypus . Nuevamente se establecen las nuevas variables, mientras que PATH tiene el sistema predeterminado.

Entonces, ¿por qué puedo establecer otras variables, pero no la variable PATH? ¿Y cómo puedo resolver esto de manera unificada ?

Actualizar:

La situación es muy desconcertante: el shell ( bashal menos) en Terminal o Emacs recogerá la RUTA que configuró launchctl, pero otras aplicaciones GUI no lo harán, por ejemplo, el script de Python mínimo mencionado directamente a través de Platypus no mostrará su personalizado camino. E incluso Emacs en sí mismo no conoce la RUTA correcta: Usted nota esto, por ejemplo, cuando emite el comando Emacs M-x ispell-buffer; la herramienta de Unix ispellque emacs intenta llamar no se encontrará si solo está en su ruta personalizada.


Apéndice

net.halloleo.environment.plist, el archivo de configuración de launchd en /Library/LaunchDaemons/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

net.halloleo.environment-user.plist, el archivo de configuración de launchd en /Library/LaunchAgents/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment-user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

/etc/profile, el archivo de inicio de bash modificado:

# System-wide .profile for sh(1)

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

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

show_environ.py, el script que muestra todas las variables de entorno:

import os
print (os.environ)
halloleo
fuente

Respuestas:

3

PATH en Yosemite puede y debe establecerse dentro del archivo / etc / paths. Simplemente agregue su ruta al final de este archivo:

/usr/bin
/bin
/your/custom/path

El script / etc / environment en la publicación original proporciona soporte para la variable PATH en aplicaciones GUI (probado con Emacs).

ursa
fuente
55
Esto solo funciona para shells que llaman /usr/libexec/path_helperdurante su proceso de inicialización. Las aplicaciones GUI no obtienen la RUTA de acuerdo con /etc/paths, y pregunté específicamente sobre las aplicaciones GUI.
halloleo
He actualizado el script de respuesta y / etc / environment en la publicación original
ursa
Estas son dos respuestas, ¿cuál está dando? También el OP dice / etc / environment no funciona
usuario151019
@mark (1) después de que surgiera esta pregunta, actualicé / etc / environment y ahora es compatible con PATH. (2) la respuesta aquí es usar / etc / caminos
ursa
2
@mark Sí, y ese es exactamente mi punto, problema y pregunta: ¿cómo puedo configurar la variable de entorno PATH de las aplicaciones GUI cuando se inician a través del Finder? Aún así, no hay una solución general real para esto a la vista ...
halloleo
2

Esto me dejó perplejo durante mucho tiempo (bueno, las últimas dos horas). Al final me encontré con este informe de error, que parece describir exactamente mi problema (no estoy seguro de hasta qué punto está relacionado con su problema, pero parece que hay un error en Yosemite / launchd en combinación con PATH y scripts tales como pitón:

http://www.openradar.me/18945659

La solución parece ser iniciar un script de shell que luego inicia el python. No es realmente lo que me gusta, pero es así ...

Claude
fuente
Gracias por el enlace al informe de error. Bueno, ahora es un error real. Encontré otro embrague a su alrededor; Lo publicaré aquí.
halloleo
1

El problema es que launchd agrega otra variable PATH en lugar de reemplazar la del entorno. La mayoría de los programas usangetenv que siempre devuelve la primera aparición de una variable, los shells en su lugar iteran a través de todas las variables de entorno e importan como variables locales, sobrescribiendo las instancias anteriores con la última.

Esto es obviamente un error en launchd, las variables de entorno pasadas a un programa deben ser únicas.

StenSoft
fuente
1
Genial respuesta de fondo! Supongo que no hay forma real de evitarlo en conchas, ¿o sí?
halloleo
@halloleo Puede iniciar el comando cuando sh -c 'YOUR ORIGINAL COMMAND'lo pasa por el shell, seleccionando el PATHconjunto en launchd.
StenSoft