Dans OSX Yosemite, pourquoi puis-je définir de nombreuses variables d'environnement pour les applications GUI, mais je ne peux pas définir la variable spécifique PATH

16

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.conffonctionnalité 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.rcscript 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_helperutilitaire dans le /etc/profil de fichier shell init , afin qu'il n'écrase pas les environment.rcparamè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_HOMEet ENVIRONMENT_RCsont définies en fonction environment.rc, mais PATH est réglé sur

/ usr / bin: / bin

Afin de m'assurer qu'aucun bashfichier 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 ( bashau 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 ispellqu'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)
halloleo
la source

Réponses:

3

PATH dans Yosemite peut et doit être défini dans le fichier / etc / chemins. Ajoutez simplement votre chemin à la fin de ce fichier:

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

Le script / etc / environment dans la publication d'origine prend en charge la variable PATH dans les applications GUI (testé avec Emacs).

Ursa
la source
5
Cela ne fonctionne que pour les shells qui appellent /usr/libexec/path_helperpendant leur processus d'initialisation. Les applications GUI n'obtiennent pas le PATH selon /etc/paths- et j'ai demandé spécifiquement des applications GUI.
halloleo
J'ai mis à jour la réponse et le script / etc / environment dans le message d'origine
ursa
Ce sont deux réponses que vous donnez - également l'OP dit que / etc / environnement ne fonctionne pas
user151019
@mark (1) après avoir posé cette question, j'ai mis à jour / etc / environment, et maintenant il prend en charge PATH. (2) la réponse ici est d'utiliser / etc / chemins
ursa
2
@mark Oui, et c'est exactement mon point, problème et question: comment puis-je définir la variable d'environnement PATH des applications GUI elles-mêmes lorsqu'elles sont lancées via le Finder? Pourtant, aucune vraie solution générale pour cela en vue ...
halloleo
2

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 ...

Claude
la source
Merci pour le lien vers le rapport de bug. Bon pour l'instant c'est un vrai bug. J'ai trouvé une autre pochette autour d'elle; Je vais le poster ici.
halloleo
1

Le problème est que launchd ajoute une autre variable PATH au lieu de remplacer celle de l'environnement. La plupart des programmes utilisent getenvqui 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.

StenSoft
la source
1
Réponse de fond cool! J'imagine que celui-ci n'est pas vraiment contourné dans les coquilles, ou y en a-t-il?
halloleo
@halloleo Vous pouvez lancer la commande telle sh -c 'YOUR ORIGINAL COMMAND'qu'elle passe par le shell, en choisissant l' PATHensemble dans launchd.
StenSoft