¿Establecer variables de entorno a través de launchd.conf ya no funciona en OS X Yosemite / El Capitan / macOS Sierra / Mojave?

190

Parece que launchd.confya no carga mi variable de entorno. Alguien más ha notado?

¿Hay otra solución para establecer permanentemente las variables de entorno?

Tosh
fuente
Funciona y está disponible en la aplicación pero no en la terminal
Chang Zhao

Respuestas:

159

Crea un environment.plistarchivo ~/Library/LaunchAgents/con este contenido:

<?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>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>
    launchctl setenv PRODUCTS_PATH /Users/mortimer/Projects/my_products
    launchctl setenv ANDROID_NDK_HOME /Applications/android-ndk
    launchctl setenv PATH $PATH:/Applications/gradle/bin
    </string>

  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Puede agregar muchos launchctlcomandos dentro del <string></string>bloque.

Se plistactivará después de reiniciar el sistema. También puede usar launchctl load ~/Library/LaunchAgents/environment.plistpara iniciarlo de inmediato.

[Editar]

La misma solución también funciona en El Capitán.

Xcode 7.0+ no evalúa las variables de entorno de forma predeterminada. El comportamiento anterior se puede habilitar con este comando:

defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool NO

[Editar]

Hay un par de situaciones en las que esto no funciona del todo. Si la computadora se reinicia y se selecciona "Reabrir ventanas al volver a iniciar sesión", es posible que las ventanas reabiertas no vean las variables (tal vez se abran antes de que se ejecute el agente). Además, si inicia sesión a través de ssh, las variables no se establecerán (por lo que deberá configurarlas en ~ / .bash_profile). Finalmente, esto no parece funcionar para PATH en El Capitan y Sierra. Eso debe establecerse a través de 'launchctl config user path ...' y en / etc / paths.

MortimerGoro
fuente
20
¡No es necesario reiniciar! Puede hacer "launchctl start environment.plist" y reiniciar la aplicación que necesita para obtener los nuevos
entornos
1
Esto no funcionaría con la variable PATH para mí. Entonces, además de este enfoque para establecer otras variables, configuré la variable PATH en mi ~ / .bash_profile. Es posible que esto no funcione para todos los casos, pero hasta ahora no tengo ningún problema.
djule5
66
Lo resolví: para trabajar sin reiniciar, debería ser "launchctl load environment.plist", no comenzar
Dave Hartnoll
2
Ah, sí. Nada como una configuración de configuración oscura que aparece exactamente 9 veces en todo Internet (google UseSanitizedBuildSystemEnvironment).
Ohad Schneider
2
También funciona en Sierra
Shwouchk
64

[ Respuesta original ]: aún puede usar launchctl setenv variablename valuepara establecer una variable para que sea recogida por todas las aplicaciones (aplicaciones gráficas iniciadas a través del Dock o Spotlight, además de las iniciadas a través del terminal).

Obviamente no querrás hacer esto cada vez que inicies sesión.

[ Editar ]: para evitar esto, inicie AppleScript Editor, ingrese un comando como este:

do shell script "launchctl setenv variablename value"

(Use varias líneas si desea establecer múltiples variables)

Ahora guarde ( + s) como Formato de archivo: Aplicación . Finalmente abra System SettingsUsuarios y gruposElementos de inicio de sesión y agregue su nueva aplicación.

[ Respuesta original ]: para evitar este lugar, todas las variables que desea definir en un script de shell corto, luego eche un vistazo a esta respuesta anterior sobre cómo ejecutar un script en el inicio de sesión de MacOS . De esa manera, el script se invocará cuando el usuario inicie sesión.

[ Editar ]: ninguna de las soluciones es perfecta ya que las variables solo se establecerán para ese usuario específico, pero espero / supongo que eso es todo lo que necesita.

Si tiene varios usuarios, puede configurar manualmente un elemento de inicio de sesión para cada uno de ellos o colocar una copia de com.user.loginscript.plist en cada uno de sus directorios locales Library / LaunchAgents , apuntando al mismo script de shell.

Por supuesto, ninguna de estas soluciones es tan conveniente como /etc/launchd.conf .

[ Edición adicional ]: Un usuario a continuación menciona que esto no funcionó para él. Sin embargo, he probado en varias máquinas de Yosemite y funciona para mí. Si tiene un problema, recuerde que deberá reiniciar las aplicaciones para que esto surta efecto. Además, si establece variables en el terminal a través de ~ / .profile o ~ / .bash_profile , anularán los elementos establecidos a través de launchctl setenv para las aplicaciones iniciadas desde el shell .

ruario
fuente
55
Por lo que puedo decir, una desventaja de esta técnica es que las variables no se establecerán para ninguna otra aplicación iniciada al iniciar sesión. Así, por ejemplo, si se abre la Terminal, la variable será conjunto, pero si cierra la sesión y volver a encender, teniendo terminal se reinicia automáticamente, la variable será desarmado ...
JASOND
He probado esta solución y tampoco me funcionó. Pero específicamente espero que mi Java IDE (IntelliJ) recoja mis modificaciones de ruta y no lo es. Todo funciona bien desde la terminal. Puede ser un error en IntelliJ. Aún frustrante que Apple haya eliminado esta funcionalidad. Llamé a Apple y no fueron de mucha ayuda.
Jason
Esto está funcionando para mí, pero ¿sabes qué hacer para agregar también las variables de entorno a sudo?
etiennenoel
2
Esto funcionará en general, sin embargo, hay un error en Yosemite (10.10.0 y 10.10.1 al menos) en el que configurar $ PATH no funciona de esta manera. Apple es consciente del error. Actualmente (a partir del 10.10.1) no existe una forma conocida de establecer un $ PATH en todo el sistema para aplicaciones GUI.
TJ Luoma
3
Después de usar uno de los métodos mencionados anteriormente y reiniciar su computadora portátil, asegúrese de volver a abrir explícitamente las aplicaciones (como iTerm, terminal, Eclipse, IDEA o lo que sea que esté usando). Si no los reinicia explícitamente y si al reiniciar OSx, la casilla de verificación estaba marcada como "Reiniciar ventanas al iniciar sesión nuevamente" (que es el valor predeterminado), esos programas no leerán las variables de entorno nuevas.
Corrió el
21

Es posible establecer variables de entorno en Mac OS X 10.10 Yosemite con 3 archivos + 2 comandos.

Archivo principal con definición de variables de entorno:

$ ls -la /etc/environment 
-r-xr-xr-x  1 root  wheel  369 Oct 21 04:42 /etc/environment
$ cat /etc/environment
#!/bin/sh

set -e

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - start"

launchctl setenv JAVA_HOME      /usr/local/jdk1.7
launchctl setenv MAVEN_HOME     /opt/local/share/java/maven3

if [ -x /usr/libexec/path_helper ]; then
    export PATH=""
    eval `/usr/libexec/path_helper -s`
    launchctl setenv PATH $PATH
fi

osascript -e 'tell app "Dock" to quit'

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - complete"

Definición del servicio para cargar variables de entorno para aplicaciones de usuario (terminal, IDE, ...):

$ ls -la /Library/LaunchAgents/environment.user.plist
-rw-------  1 root  wheel  504 Oct 21 04:37 /Library/LaunchAgents/environment.user.plist
$ sudo cat /Library/LaunchAgents/environment.user.plist
<?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>Label</key>
    <string>environment.user</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

La misma definición de servicio para aplicaciones de usuario root:

$ ls -la /Library/LaunchDaemons/environment.plist
-rw-------  1 root  wheel  499 Oct 21 04:38 /Library/LaunchDaemons/environment.plist
$ sudo cat /Library/LaunchDaemons/environment.plist
<?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>Label</key>
    <string>environment</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

Y finalmente debemos registrar estos servicios:

$ launchctl load -w /Library/LaunchAgents/environment.user.plist
$ sudo launchctl load -w /Library/LaunchDaemons/environment.plist

Lo que obtenemos:

  1. El único lugar para declarar variables de entorno del sistema: / etc / environment
  2. Actualización automática instantánea de las variables de entorno después de la modificación del archivo / etc / environment: solo reinicie su aplicación

Problemas / problemas:

Para que las aplicaciones envíen sus variables env correctamente después del reinicio del sistema , necesitará:

  • ya sea iniciar sesión dos veces: login => logout => login
  • o cierre y vuelva a abrir aplicaciones manualmente, donde se deben tomar las variables env
  • o NO use la función "Reabrir ventanas al volver a iniciar sesión".

Esto sucede debido a que Apple niega el pedido explícito de los servicios cargados, por lo que las variables env se registran en paralelo con el procesamiento de la "cola de reapertura".

Pero en realidad, reinicio mi sistema solo varias veces al año (en grandes actualizaciones), por lo que no es un gran problema.

ursa
fuente
Gran idea. Lo he intentado y funciona para la mayoría de las variables de entorno (como JAVA_HOME), pero no para la PATHvariable (vea mi pregunta sobre preguntar diferente ).
halloleo
44
PATH debe establecerse con el archivo / etc / paths. Simplemente agregue su ruta personalizada al final de este archivo.
ursa
No estoy tan familiarizado launchd, pero ¿no sería posible cargar esos Daemons en el arranque (es decir, antes de iniciar sesión)? Eso debería eludir todos los problemas que mencionas.
Egon
Me encanta el enfoque anterior, pero tengo un problema extraño que manejar. Después de reiniciar un genet, VARNAME me devuelve el valor correcto, pero echo $ VARNAME no devuelve nada. ¿Cuál podría ser una razón para esto? Lo publiqué en stackoverflow.com/questions/27045137/… también y espero que alguien aquí tenga una idea
ctp
Asegúrese de que los permisos de archivo de / etc / environment sean los descritos anteriormente.
imanuelcostigan
6

Citado de

Apple Developer Relations 10-Oct-2014 09:12 PM

Después de mucha deliberación, la ingeniería ha eliminado esta característica. El archivo /etc/launchd.conffue eliminado intencionalmente por razones de seguridad. Como solución alternativa, puede ejecutar launchctl limitcomo root temprano durante el arranque, tal vez desde a LaunchDaemon. (...)

Solución:

Poner código en /Library/LaunchDaemons/com.apple.launchd.limit.plistpor bash-script:

#!/bin/bash

echo '<?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>Label</key>
        <string>eicar</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/launchctl</string>
                <string>limit</string>
                <string>core</string>
                <string>unlimited</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceIPC</key>
        <false/>
</dict>
</plist>' | sudo tee /Library/LaunchDaemons/com.apple.launchd.limit.plist
aax
fuente
1
¿Puedes explicar esto un poco más? ¡No puedo ver cómo el 'Solucionar problema' se relaciona con el problema inicial!
Nick H247
No es el OP, pero creo que lo esencial aquí es: poner este plist en /Library/LaunchDaemons, y en lugar de decirle launchctlque ejecute el limitcomando, dígale que ejecute el setenvcomando con PATHuna cadena de ruta como argumentos. launchddebería recogerlo automáticamente al inicio y obtener una especie de auto-modificación casi de inmediato.
Laird Nelson
55
El xml está copiado de forma incompleta. La línea doctype debería leer<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
UloPe
66
@aax, ¿qué parte de esa lista establece realmente una variable de entorno?
HairOfTheDog
3

Estos son los comandos para restaurar el comportamiento anterior:

# create a script that calls launchctl iterating through /etc/launchd.conf
echo '#!/bin/sh

while read line || [[ -n $line ]] ; do launchctl $line ; done < /etc/launchd.conf;
' > /usr/local/bin/launchd.conf.sh

# make it executable
chmod +x /usr/local/bin/launchd.conf.sh

# launch the script at startup
echo '<?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>Label</key>
  <string>launchd.conf</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>/usr/local/bin/launchd.conf.sh</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
' > /Library/LaunchAgents/launchd.conf.plist

Ahora puede especificar comandos como setenv JAVA_HOME /Library/Java/Homeen /etc/launchd.conf.

Comprobado en El Capitan.

Yanchenko
fuente
2

Lo que funcionó para mí (inspirado por aax 'gracias):

Pegue esto en /Library/LaunchDaemons/com.apple.launchd.limit.plist y luego reinicie:

<?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>Label</key>
  <string>eicar</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>limit</string>
    <string>maxfiles</string>
    <string>16384</string>
    <string>16384</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

Si lo necesitas paso a paso:

  • Terminal de lanzamiento
  • Escriba sudo su y luego ingrese su contraseña para iniciar sesión como root
  • Escriba vi /Library/LaunchDaemons/com.apple.launchd.limit.plist
  • Cuando esté en el editor vi, presione la tecla i para ingresar al modo de inserción y luego pegue el contenido del código exacto arriba ( ⌘+v). Esto forzará el límite a 16384 archivos por proceso y 16384 archivos en total
  • Guarde su archivo y salga usando escluego:wq
  • Reinicie su sistema y verifique que esté funcionando usando el comando launchctl limit

espero que esto te ayude.

Baptiste
fuente
10
¿Qué tiene que ver esta solución con la configuración de variables de entorno?
HairOfTheDog
2

Puedes probar https://github.com/ersiner/osx-env-sync . Maneja tanto la línea de comandos como las aplicaciones GUI desde una sola fuente y funciona con la última versión de OS X (Yosemite).

Puede usar sustituciones de ruta y otros trucos de shell, ya que lo que escribe es un script bash regular que se obtiene de bash en primer lugar. Sin restricciones. (Consulte la documentación de osx-env-sync y comprenderá cómo lo logra).

Respondí una pregunta similar aquí donde encontrarás más.

Ersin Er
fuente
-3

La solución es agregar su variable a /etc/profile. ¡Entonces todo funciona como se esperaba! Por supuesto, DEBE hacerlo como usuario root con sudo nano / etc / profile. Si lo edita de alguna otra manera, el sistema se quejará con un perfil / etc / dañado, incluso si cambia los permisos a root.

Ilias
fuente
77
Agregar variables de entorno al perfil es muy inferior ya que solo afecta los procesos de shell.
UloPe
-5

Agregué las variables en el ~ / .bash_profile de la siguiente manera. Una vez que haya terminado, reinicie / cierre sesión e inicie sesión

export M2_HOME=/Users/robin/softwares/apache-maven-3.2.3
export ANT_HOME=/Users/robin/softwares/apache-ant-1.9.4
launchctl setenv M2_HOME $M2_HOME
launchctl setenv ANT_HOME $ANT_HOME
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/robin/softwares/apache-maven-3.2.3/bin:/Users/robin/softwares/apache-ant-1.9.4/bin
launchctl setenv PATH $PATH

NOTA: sin reiniciar / cerrar sesión e iniciar sesión puede aplicar estos cambios usando;

source ~/.bash_profile
Robin
fuente
Tenga en cuenta que no tiene que cerrar la sesión y volver a iniciarla. Simplemente use el comando de origen, es decir, fuente .bash_profile.
Michael
2
Además, el problema con este método es que aún tiene que abrir un terminal antes de que las variables de entorno estén disponibles. Es mejor hacer lo que está en la primera respuesta para que estén disponibles sin tener que abrir un terminal.
Michael
1
Esto no funciona en aplicaciones cargadas a través de SpotLight. stackoverflow.com/questions/135688/…
Rasika Perera
1
El uso de los archivos de configuración de bash es de ayuda limitada, ya que supone que siempre has tenido bash como un antepasado del proceso cuyo entorno estás tratando de llevar a cabo. Spotlight, el buscador, emacs, xcode, cronjobs, agentes de launchd, cualquier IDE, navegadores de control de fuente, etc., etc., no van a tener bash como ancestro. El único proceso que puede abarcar estos consistentemente es el lanzamiento.
Ben Hyde