[macos] Establecer variables de entorno en OS X?



13 Answers

Cómo configurar el entorno para nuevos procesos iniciado por Spotlight (sin necesidad de reiniciar)

Puede configurar el entorno utilizado por launchd (y, por extensión, cualquier cosa iniciada desde Spotlight) con launchctl setenv . Por ejemplo, para establecer la ruta:

launchctl setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

O si desea configurar su ruta en .bashrc o similar, .bashrc que se refleje en launchd:

PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv PATH $PATH

No es necesario reiniciar, aunque deberá reiniciar una aplicación si desea que recupere el entorno modificado.

Esto incluye todas las shells que ya se ejecutan bajo Terminal.app, aunque si estás allí puedes establecer el entorno más directamente, por ejemplo, con export PATH=/opt/local/bin:/opt/local/sbin:$PATH para bash o zsh .

Cómo mantener los cambios después de un reinicio

Para mantener los cambios después de un reinicio , puede configurar las variables de entorno desde /etc/launchd.conf , así:

setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

launchd.conf se ejecuta automáticamente cuando reinicias.

Si desea que estos cambios surtan efecto ahora, debe usar este comando para reprocesar launchctl.conf (¡gracias @mklement por la sugerencia!)

egrep -v '^\s*#' /etc/launchd.conf | launchctl

Puede obtener más información sobre launchctl y cómo carga launchd.conf con el comando man launchctl .

Question

¿Cuál es la forma correcta de modificar variables de entorno como PATH en OSX? He buscado un poco en Google y encontré 3 archivos diferentes para editar:

  • / etc / paths
  • ~ / .profile
  • ~ / .tcshrc

Ni siquiera tengo algunos de estos archivos, y estoy bastante seguro de que .tcshrc está mal, ya que OSX usa bash ahora. ¿Alguien tiene alguna idea de dónde se definen estas variables, especialmente PATH?

Editar: estoy ejecutando OS X 10.5




Básicamente hay dos problemas para resolver cuando se trata de variables de entorno en OS X. El primero es cuando se invocan programas de Spotlight (el icono de lupa en el lado derecho del menú / barra de estado de Mac) y el segundo cuando se invocan programas desde el Dock . Invocar programas desde una aplicación / utilidad de Terminal es trivial porque lee el entorno desde las ubicaciones de shell estándar ( ~/.profile , ~/.bash_profile , ~/.bashrc , etc.)

Al invocar programas desde el Dock, use ~/.MacOSX/environment.plist donde el elemento <dict> contiene una secuencia de elementos <key>KEY</key><string>theValue</string> .

Cuando invoque programas de Spotlight, asegúrese de que launchd se haya configurado con todas las configuraciones de clave / valor que necesita.

Para resolver ambos problemas simultáneamente, utilizo un elemento de inicio de sesión (configurado a través de la herramienta de Preferencias del sistema) en mi cuenta de usuario. El elemento de inicio de sesión es un script bash que invoca una función de ceceo de Emacs aunque, por supuesto, puede usar su herramienta de scripting favorita para lograr lo mismo. Este enfoque tiene la ventaja adicional de que funciona en cualquier momento y no requiere un reinicio, es decir, uno puede editar ~/.profile , ejecutar el elemento de inicio de sesión en algún shell y tener los cambios visibles para los programas recién invocados, desde el Dock o Destacar.

Detalles:

~/bin/macosx-startup sesión: ~/bin/macosx-startup

#!/bin/bash
bash -l -c "/Applications/Emacs.app/Contents/MacOS/Emacs --batch -l ~/lib/emacs/elisp/macosx/environment-support.el -f generate-environment"

Función Emacs lisp: ~/lib/emacs/elisp/macosx/envionment-support.el

;;; Provide support for the environment on Mac OS X

(defun generate-environment ()
  "Dump the current environment into the ~/.MacOSX/environment.plist file."
  ;; The system environment is found in the global variable:
  ;; 'initial-environment' as a list of "KEY=VALUE" pairs.
  (let ((list initial-environment)
        pair start command key value)
    ;; clear out the current environment settings
    (find-file "~/.MacOSX/environment.plist")
    (goto-char (point-min))
    (setq start (search-forward "<dict>\n"))
    (search-forward "</dict>")
    (beginning-of-line)
    (delete-region start (point))
    (while list
      (setq pair (split-string (car list) "=")
            list (cdr list))
      (setq key (nth 0 pair)
            value (nth 1 pair))
      (insert "  <key>" key "</key>\n")
      (insert "  <string>" value "</string>\n")

      ;; Enable this variable in launchd
      (setq command (format "launchctl setenv %s \"%s\"" key value))
      (shell-command command))
    ;; Save the buffer.
    (save-buffer)))

NOTA: Esta solución es una amalgama de las que vienen antes de que yo agregue la mía, particularmente la ofrecida por Matt Curtis, pero deliberadamente he intentado mantener mi plataforma de contenido ~/.bash_profile independiente y establecer el entorno de lanzamiento (una instalación única de Mac) ) en un script separado.




Just did this really easy and quick. First create a ~/.bash_profile from terminal:

touch .bash_profile

entonces

open -a TextEdit.app .bash_profile

añadir

export TOMCAT_HOME=/Library/Tomcat/Home

save documement and you are done.




Actualización (2017-08-04)

A partir de (al menos) macOS 10.12.6 (Sierra), este método parece haber dejado de funcionar para Apache httpd (tanto para el system como para la opción de user de launchctl config ). Otros programas no parecen verse afectados. Es concebible que esto sea un error en httpd.

Respuesta original

Esto se refiere a OS X 10.10+ (10.11+ específicamente debido al modo sin raíz donde /usr/bin ya no es grabable).

He leído en varios lugares que el uso de launchctl setenv PATH <new path> para establecer la variable PATH no funciona debido a un error en OS X (lo que parece cierto por experiencia personal). Descubrí que hay otra manera en que se puede configurar PATH para aplicaciones que no se iniciaron desde el shell :

sudo launchctl config user path <new path>

Esta opción está documentada en la página man de launchctl:

sistema de configuración | valor del parámetro de usuario

Establece la información de configuración persistente para dominios launchd (8). Solo el dominio del sistema y los dominios del usuario pueden ser configurados. La ubicación del almacenamiento persistente es un detalle de implementación, y los cambios en ese almacenamiento solo deben realizarse a través de este subcomando. Se requiere reiniciar para que los cambios realizados a través de este subcomando entren en vigencia.

[...]

camino

Establece la variable de entorno PATH para todos los servicios dentro del dominio de destino en el valor de cadena. El valor de cadena debe ajustarse al formato descrito para la variable de entorno PATH en environ (7). Tenga en cuenta que si un servicio especifica su propia RUTA, la variable de entorno específica del servicio tendrá prioridad.

NOTA: Esta función no se puede usar para establecer variables de entorno generales para todos los servicios dentro del dominio. Tiene un alcance intencional para la variable de entorno PATH y nada más por razones de seguridad.

He confirmado que esto funciona con una aplicación GUI iniciada desde Finder (que usa getenv para obtener PATH). Tenga en cuenta que solo tiene que hacer esto una vez y el cambio será persistente a través de reinicios.




well, I'm unsure about /etc/paths and ~/.MacOSX/environment.plist those are new.

But with bash, you should know that .bashrc is executed with every new shell invocation and .bash_profile is only executed once at startup. Don't know how often this is with macos, I think the distinction has broken down with the window system launching everything.

Personally, I eliminate the confusion by creating a .bashrc with everything I need and then do:

ln -s .bashrc .bash_profile



Solución para aplicaciones de línea de comando y GUI desde una única fuente (funciona con Yosemite y El Capitan)

Supongamos que tiene definiciones de variables de entorno en su ~/.bash_profile como en el siguiente fragmento de código:

export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
export GOPATH="$HOME/go"
export PATH="$PATH:/usr/local/opt/go/libexec/bin:$GOPATH/bin"
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"

Necesitamos un agente de inicio que se ejecutará en cada inicio de sesión y en cualquier momento bajo demanda que va a cargar estas variables a la sesión del usuario. También necesitaremos un script de shell para analizar estas definiciones y crear los comandos necesarios para que el agente los ejecute.

Cree un archivo con sufijo plist (por ejemplo, llamado osx-env-sync.plist ) en el directorio ~/Library/LaunchAgents/ con los siguientes contenidos:

<?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>osx-env-sync</string>
  <key>ProgramArguments</key>
  <array>
    <string>bash</string>
    <string>-l</string>
    <string>-c</string>
    <string>
      $HOME/.osx-env-sync.sh
    </string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

-l parámetro es crítico aquí; es necesario para ejecutar el script de shell con un shell de inicio de sesión para que ~/.bash_profile se obtenga en primer lugar antes de que se ejecute este script.

Ahora, el script de shell. ~/.osx-env-sync.sh en ~/.osx-env-sync.sh con los siguientes contenidos:

grep export $HOME/.bash_profile | while IFS=' =' read ignoreexport envvar ignorevalue; do
  launchctl setenv ${envvar} ${!envvar}
done

Asegúrese de que el script de shell sea ejecutable:

chmod +x ~/.osx-env-sync.sh

Ahora, cargue el agente de lanzamiento para la sesión actual:

launchctl load ~/Library/LaunchAgents/osx-env-sync.plist

(Re) Inicie una aplicación GUI y verifique que pueda leer las variables de entorno.

La configuración es persistente. Sobrevivirá a reinicios y relogines.

Después de la configuración inicial (que acabas de hacer), si deseas reflejar cualquier cambio en tu ~/.bash_profile en todo tu entorno nuevamente, volver a ejecutar el launchctl load ... no realizará lo que quieras; en su lugar, recibirá una advertencia como la siguiente:

<$HOME>/Library/LaunchAgents/osx-env-sync.plist: Operation already in progress

Para volver a cargar las variables de entorno sin pasar por el proceso de cierre de sesión / inicio de sesión, haga lo siguiente:

launchctl unload ~/Library/LaunchAgents/osx-env-sync.plist
launchctl load ~/Library/LaunchAgents/osx-env-sync.plist

Finalmente, asegúrese de reiniciar las aplicaciones que ya está ejecutando (incluida Terminal.app) para informarlas sobre los cambios.

También introduje el código y las explicaciones aquí en un proyecto de GitHub: osx-env-sync .

Espero que esta sea la solución definitiva, al menos para las últimas versiones de OS X (Yosemite y El Capitán).







Setup your PATH environment variable on Mac OS

Open the Terminal program (this is in your Applications/Utilites folder by default). Run the following command touch ~/.bash_profile; open ~/.bash_profile This will open the file in the your default text editor.

For ANDROID SDK as example :

You need to add the path to your Android SDK platform-tools and tools directory. In my example I will use "/Development/android-sdk-macosx" as the directory the SDK is installed in. Add the following line:

export PATH=${PATH}:/Development/android-sdk-macosx/platform-tools:/Development/android-sdk-macosx/tools

Save the file and quit the text editor. Execute your .bash_profile to update your PATH.

source ~/.bash_profile

Now everytime you open the Terminal program you PATH will included the Android SDK.




For Bash, try adding your environment variables to the file /etc/profile to make them available for all users. No need to reboot, just start a new Terminal session.




¡En Mountain Lion, todas las /etc/launchd.conf /etc/paths y /etc/launchd.conf no tienen ningún efecto!

Los foros de desarrolladores de Apple dicen:

"Cambie Info.plist del .app mismo para que contenga un diccionario" LSEnvironment "con las variables de entorno que desee.

~ / .MacOSX / environment.plist ya no es compatible. "

Así que Info.plist directamente el Info.plist la aplicación (haga clic con el botón derecho en "AppName.app" (en este caso SourceTree) y luego " Show package contents ")

y agregó un nuevo par clave / dict llamado:

<key>LSEnvironment</key>
<dict>
     <key>PATH</key>
     <string>/Users/flori/.rvm/gems/ruby-1.9.3-p362/bin:/Users/flori/.rvm/gems/ruby-1.9.3-p362@global/bin:/Users/flori/.rvm/rubies/ruby-1.9.3-p326/bin:/Users/flori/.rvm/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:</string>
</dict>

(ver: LaunchServicesKeys Documentation at Apple )

ahora la aplicación (en mi caso SourceTree) usa la ruta dada y funciona con git 1.9.3 :-)

PD: por supuesto, debe ajustar la entrada de ruta a sus necesidades específicas de ruta.







Al igual que la respuesta dada por Matt Curtis, establezco variables de entorno a través de launchctl, pero la envuelvo en una función llamada export, de modo que cada vez que exporto una variable como normal en mi .bash_profile, también se establece mediante launchctl. Esto es lo que hago:

  1. Mi .bash_profile consiste únicamente de una línea, (Esto es solo preferencia personal).

    source .bashrc
    
  2. Mi .bashrc tiene esto:

    function export()
    {
        builtin export "$@"
        if [[ ${#@} -eq 1 && "${@//[^=]/}" ]]
        then
            launchctl setenv "${@%%=*}" "${@#*=}"
        elif [[ ! "${@//[^ ]/}" ]]
        then
            launchctl setenv "${@}" "${!@}"
        fi
    }
    
    export -f export
    
  3. Lo anterior sobrecargará la "exportación" Bash incorporada y exportará todo normalmente (¡notarás que exporto "exportar" con ella!), Luego los configurará correctamente para los entornos de la aplicación OS X a través de launchctl, ya sea que uses cualquiera de los siguientes:

    export LC_CTYPE=en_US.UTF-8
    # ~$ launchctl getenv LC_CTYPE
    # en_US.UTF-8
    PATH="/usr/local/bin:${PATH}"
    PATH="/usr/local/opt/coreutils/libexec/gnubin:${PATH}"
    export PATH
    # ~$ launchctl getenv PATH
    # /usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
    export CXX_FLAGS="-mmacosx-version-min=10.9"
    # ~$ launchctl getenv CXX_FLAGS
    # -mmacosx-version-min=10.9
    
  4. De esta forma, no tengo que enviar todas las variables a launchctl todo el tiempo, y puedo simplemente configurar mi .bash_profile / .bashrc configurado de la manera que quiero. Abra una ventana de terminal, revise las variables de entorno que le interesan con launchctl getenv myVar , cambie algo en su launchctl getenv myVar / .bashrc, cierre la ventana del terminal y vuelva a abrirlo, compruebe la variable nuevamente con launchctl y voilá, ha cambiado

  5. Una vez más, al igual que las otras soluciones para el mundo posterior al Mountain Lion, para que las nuevas variables de entorno estén disponibles para las aplicaciones, debe iniciarlas o relanzarlas después del cambio.




There are two type of shells at play here.

  • Non-Login: .bashrc is reloaded every time you start a new copy of bash
  • Login: The .profile is loaded only when you either login, or explicitly tell bash to load it and use it as a login shell.

Its important to understand here that with bash .bashrc is only read by a shell that's both interactive and non-login, and you will find that people often load .bashrc in .bash_profile to overcome this limitation.

Now that you have the basic understanding, lets move on to how i would advice you to set it up.

  • .profile: create it non-existing. Put your PATH setup in there.
  • .bashrc: create if non-existing. Put all your Aliases and Custom method in there.
  • .bash_profile: create if non-existing. Put the following in there.

.bash_file:

#!/bin/bash
source ~/.profile # Get the PATH settings
source ~/.bashrc  # Get Aliases and Functions
#



A veces, todas las respuestas anteriores simplemente no funcionan. Si desea tener acceso a una variable del sistema (como M2_HOME) en Eclipse o en IntelliJ, lo único que funciona para mí en este caso es:

Primero (paso 1) edite /etc/launchd.conf para contener una línea como esta: "setenv VAR value" y luego (paso 2) reiniciar.

La simple modificación de .bash_profile no funcionará porque en OSX las aplicaciones no se inician como en otros UNIX, no heredan las variables de shell de los padres. Todas las demás modificaciones no funcionarán por una razón que desconozco. Tal vez alguien más pueda aclarar sobre esto.






Related