Après avoir réglé les problèmes de PATH d'OSX jusqu'à la sortie des Mavericks, les problèmes reviennent dans Yosemite !!!
Je veux donc imiter l'ancienne launch.conf
fonctionnalité de la nouvelle version de Mac OSX 10.10 Yosemite, afin d'avoir la variable d'environnement PATH dans les applications GUI comme Carbon Emacs ou RStudio . J'ai utilisé la grande idée de l'utilisateur de stackoverflow ursa pour mettre en place un script shell qui configure les variables d'environnement via launchctl
. (Voir sa réponse stackoverflow ici .) Cela fonctionne pour la plupart des variables d'environnement, mais pas pour la variable PATH .
1. Qu'est-ce que j'ai fait?
J'ai d'abord écrit le /etc/environment.rc
script comme suit:
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"
J'ai ensuite créé les plists pour launchd
(liste de ceux-ci et des autres scripts mentionnés dans l'annexe ci-dessous). Ensuite, je les ai activés avec
$ sudo launchctrl load ...
Ensuite, j'ai désactivé l' path_helper
utilitaire dans le /etc/
profil de fichier shell init , afin qu'il n'écrase pas les environment.rc
paramètres. Et finalement j'ai redémarré la machine.
2. Quel est l'effet?
Lorsque je démarre Terminal les nouvelles variables d'environnement JAVA_HOME
et ENVIRONMENT_RC
sont définies en fonction environment.rc
, mais PATH est réglé sur
/ usr / bin: / bin
Afin de m'assurer qu'aucun bash
fichier init ne me gêne, j'ai plutôt écrit un petit script python (dans l'annexe également) pour afficher les variables dans l'environnement actuel et je l'exécute directement en double-cliquant sur un wrapper Platypus . Encore une fois, les nouvelles variables sont définies, tandis que PATH a la valeur par défaut du système.
Alors, pourquoi puis-je définir d'autres variables, mais pas la variable PATH? Et comment puis-je résoudre ce problème de manière unifiée ?
Mise à jour:
La situation est très déroutante: le shell ( bash
au moins) dans Terminal ou Emacs récupérera le CHEMIN que vous avez défini via launchctl
, mais d'autres applications GUI ne le feront pas., Par exemple, le script python minimal mentionné directement appelé via Platypus ne montrera pas votre personnalisé chemin. Et même Emacs lui-même ne connaît pas le chemin correct: vous le remarquez par exemple lorsque vous émettez la commande Emacs M-x ispell-buffer
; l'outil unix ispell
qu'emacs essaie d'appeler ne sera pas trouvé s'il se trouve uniquement sur votre chemin personnalisé.
appendice
net.halloleo.environment.plist
, le fichier de configuration launchd dans /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
, le fichier de configuration launchd dans /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
, le fichier de démarrage bash modifié:
# 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
, le script affichant toutes les variables d'environnement:
import os
print (os.environ)
la source
/usr/libexec/path_helper
pendant leur processus d'initialisation. Les applications GUI n'obtiennent pas le PATH selon/etc/paths
- et j'ai demandé spécifiquement des applications GUI.Cela m'a laissé perplexe pendant longtemps (enfin, les dernières heures). En fin de compte, j'ai rencontré ce rapport de bogue, qui semble décrire exactement mon problème (je ne sais pas dans quelle mesure il est lié à votre problème, mais il semble y avoir un bogue dans Yosemite / launchd en combinaison avec PATH et des scripts tels que comme python:
http://www.openradar.me/18945659
La solution semble être de démarrer un script shell qui démarre ensuite le python. Pas vraiment ce que j'aime, mais c'est comme ça ...
la source
Le problème est que launchd ajoute une autre variable PATH au lieu de remplacer celle de l'environnement. La plupart des programmes utilisent
getenv
qui retourne toujours la première occurrence d'une variable, les shells parcourent à la place toutes les variables d'environnement et les importent en tant que variables locales, remplaçant ainsi les instances précédentes par la dernière.C'est évidemment un bug dans launchd, les variables d'environnement passées à un programme doivent être uniques.
la source
sh -c 'YOUR ORIGINAL COMMAND'
qu'elle passe par le shell, en choisissant l'PATH
ensemble dans launchd.