16 votes

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

Après que j'ai résolution des problèmes de PATH d'OSX jusqu'à la sortie de Mavericks, les problèmes reviennent dans Yosemite ! !!

Donc je veux imiter l'ancien launch.conf dans la nouvelle version Mac OSX 10.10 Yosemite, afin d'avoir la variable d'environnement PATH dans les applications GUI comme Carbon Emacs o RStudio disponible. J'ai utilisé l'idée géniale de l'utilisateur de stackoverflow ursa pour mettre en place un shell script qui configure les variables d'environnement par l'intermédiaire de launchctl . (Voir sa réponse sur 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 ressemblant à :

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"

Puis j'ai créé les plists pour launchd (listes de ceux-ci et d'autres scripts mentionnés dans l'annexe ci-dessous). Puis je les ai activés avec

$ sudo launchctrl load ...

Ensuite, j'ai désactivé le path_helper dans le fichier d'initialisation du shell /etc/ de sorte qu'il n'écrase pas le profil environment.rc paramètres. Et enfin, j'ai redémarré la machine.

2. Quel est l'effet ?

Quand je démarre le terminal, les nouvelles variables d'environnement JAVA_HOME et ENVIRONMENT_RC sont fixés en fonction de environment.rc mais PATH est défini comme suit

/usr/bin:/bin

Afin de s'assurer, qu'aucun bash s'est trouvé dans le chemin, j'ai écrit un petit Python script à la place (dans l'appendice aussi) pour montrer les variables dans l'environnement actuel et je l'exécute directement en double cliquant sur un fichier L'ornithorynque l'emballage. Encore une fois, les nouvelles variables sont définies, tandis que PATH a la valeur par défaut du système.

Alors pourquoi je peux définir d'autres variables, mais no la variable PATH ? Et comment puis-je résoudre ce problème d'une manière unifiée ?

Mise à jour :

La situation est très déroutante : Le coquillage ( bash au moins) dans Terminal ou Emacs reprendra le PATH que vous avez défini par le biais de launchctl Par exemple, l'application minimale Python script mentionnée, appelée directement par Platypus, ne montrera pas votre chemin personnalisé. Et Emacs lui-même ne connaît pas le PATH correct : vous le remarquez par exemple lorsque vous lancez la commande Emacs M-x ispell-buffer ; l'outil unix ispell qu'emacs essaie d'appeler ne sera pas trouvé s'il se trouve juste sur votre chemin personnalisé.


Annexe

net.halloleo.environment.plist le fichier de configuration de 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 de 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)

3voto

ursa Points 147

PATH dans Yosemite peut et doit être défini dans le fichier /etc/paths. Il suffit d'ajouter votre chemin à la fin de ce fichier :

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

/etc/environnement script en poste original fournit un support pour la variable PATH dans les applications GUI (testé avec Emacs).

6 votes

Il s'agit de o fonctionnent pour les coquilles qui appellent /usr/libexec/path_helper au cours de leur processus d'initialisation. Les applications GUI font pas obtenir le PATH en fonction de /etc/paths - et j'ai posé une question spécifique sur les applications graphiques.

0 votes

J'ai mis à jour la réponse et le fichier /etc/environment script dans le message original.

0 votes

Il s'agit de deux réponses, laquelle donnez-vous ? De plus, l'OP dit que /etc/environment ne fonctionne pas.

2voto

Claude Points 186

Cela m'a laissé perplexe pendant un long moment (enfin, les deux dernières heures). Finalement, je suis tombé sur ce rapport de bogue, qui semble décrire exactement mon problème (je ne suis pas sûr dans quelle mesure il est lié à votre problème, mais il semble y avoir un bogue dans Yosemite/launchd en combinaison avec PATH et scripts tels que Python :

http://www.openradar.me/18945659

La solution semble être de lancer un shell script qui lance ensuite le Python. Ce n'est pas vraiment ce que j'aime, mais c'est comme ça.....

0 votes

Merci pour le lien vers le rapport de bogue. Il est bon de savoir qu'il s'agit d'un vrai bug. J'ai trouvé un autre moyen de le contourner ; je le posterai ici.

1voto

StenSoft Points 111

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 renvoie toujours la première occurrence d'une variable, les coquilles itèrent à la place à travers toutes les variables d'environnement et les importent comme variables locales, écrasant ainsi les instances précédentes avec la dernière.

Il s'agit manifestement d'un bogue dans launchd, les variables d'environnement passées à un programme doivent être uniques.

1 votes

Superbe réponse sur le fond ! Je suppose qu'il n'y a pas vraiment de moyen de contourner le problème dans les coquillages, ou bien est-ce le cas ?

0 votes

@halloleo Vous pouvez lancer la commande en tant que sh -c 'YOUR ORIGINAL COMMAND' qui le fait passer par le shell, en choisissant le PATH dans launchd.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X