Warum kann ich in OSX Yosemite viele Umgebungsvariablen für GUI-Apps festlegen, aber nicht die spezifische Variable PATH

16

Nachdem ich die PATH-Probleme von OSX bis zur Veröffentlichung von Mavericks geklärt hatte, tauchen die Probleme in Yosemite wieder auf !!!

Daher möchte ich die alte launch.confFunktion in der neuen Yosemite-Version von Mac OSX 10.10 nachahmen , um die Umgebungsvariable PATH in GUI-Apps wie Carbon Emacs oder RStudio verfügbar zu haben. Ich habe die großartige Idee des Stackoverflow-Benutzers ursa genutzt , um ein Shell-Skript einzurichten, mit dem Umgebungsvariablen über konfiguriert werden launchctl. (Die Antwort auf den Stackoverflow finden Sie hier .) Dies funktioniert für die meisten Umgebungsvariablen, jedoch nicht für die PATH-Variable .

1. Was habe ich getan?

Zuerst habe ich das /etc/environment.rcSkript so geschrieben:

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"

Dann habe ich die Plists für erstellt launchd(Auflistungen dieser und der anderen erwähnten Skripte im Anhang unten). Dann habe ich sie mit aktiviert

$ sudo launchctrl load ...

Dann habe ich das path_helperDienstprogramm im Shell-Init-Dateiprofil deaktiviert /etc/, damit es die environment.rcEinstellungen nicht überschreibt . Und schließlich habe ich die Maschine neu gestartet.

2. Was ist der Effekt?

Wenn ich starten Terminal die neuen Umgebungsvariablen JAVA_HOMEund ENVIRONMENT_RCwerden entsprechend environment.rc, aber PATH gesetzt ist

/ usr / bin: / bin

Um sicherzugehen, dass keine bashInit-Datei im Weg ist, habe ich stattdessen (auch im Anhang) ein kleines Python-Skript geschrieben, um die Variablen in der aktuellen Umgebung anzuzeigen, und ich führe dies direkt durch Doppelklick auf einen Platypus- Wrapper aus. Wieder werden die neuen Variablen gesetzt, während PATH den Systemstandard hat.

Warum kann ich also andere Variablen festlegen, aber nicht die PATH-Variable? Und wie kann ich das auf einheitliche Weise lösen ?

Aktualisieren:

Die Situation ist sehr rätselhaft: Die Shell ( bashzumindest) in Terminal oder Emacs übernimmt den Pfad, den Sie über festgelegt haben launchctl, andere GUI-Apps tun dies jedoch nicht. Beispiel: Das erwähnte minimale Python-Skript, das direkt über Platypus aufgerufen wird, zeigt Ihren benutzerdefinierten Pfad nicht an Pfad. Und selbst Emacs selbst kennt den korrekten PFAD nicht: Sie bemerken dies z. B., wenn Sie den Emacs-Befehl eingeben M-x ispell-buffer. Das Unix-Tool, ispelldas Emacs aufzurufen versucht, wird nicht gefunden, wenn es sich nur auf Ihrem benutzerdefinierten Pfad befindet.


Blinddarm

net.halloleo.environment.plist, die launchd Konfigurationsdatei in /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, die launchd Konfigurationsdatei in /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, die modifizierte Bash-Startdatei:

# 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, das Skript, das alle Umgebungsvariablen anzeigt:

import os
print (os.environ)
halloleo
quelle

Antworten:

3

PATH in Yosemite kann und sollte in der Datei / etc / arrows festgelegt werden. Fügen Sie einfach Ihren Pfad an das Ende dieser Datei an:

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

Das Skript / etc / environment im ursprünglichen Beitrag unterstützt die Variable PATH in GUI-Anwendungen (getestet mit Emacs).

ursa
quelle
5
Dies funktioniert nur für Shells, die /usr/libexec/path_helperwährend ihres Initialisierungsprozesses aufgerufen werden. GUI - Anwendungen nicht nicht erhalten die PATH nach /etc/paths- und ich ausdrücklich darum gebeten , über GUI - Anwendungen.
Halloleo
Ich habe Antwort- und / etc / environment-Skript im ursprünglichen Beitrag aktualisiert
ursa
Dies sind zwei Antworten, die Sie geben - auch das OP sagt, dass / etc / environment nicht funktioniert
user151019
@mark (1) nachdem diese Frage aufgeworfen wurde, habe ich / etc / environment aktualisiert und jetzt unterstützt es PATH. (2) die antwort hier ist / etc /
ursa
2
@mark Ja, und genau das ist mein Punkt, Problem und Frage: Wie kann ich die Umgebungsvariable PATH von GUI-Apps selbst festlegen, wenn sie über den Finder gestartet werden? Trotzdem ist keine generelle Lösung in Sicht ...
halloleo
2

Das hat mich lange verwirrt (naja, die letzten paar Stunden). Am Ende bin ich auf diesen Fehlerbericht gestoßen, der mein Problem genau zu beschreiben scheint (ich bin mir nicht sicher, inwieweit er mit Ihrem Problem zusammenhängt, aber es scheint einen Fehler in Yosemite / launchd in Kombination mit PATH und Skripten wie z als Python:

http://www.openradar.me/18945659

Die Lösung scheint zu sein, ein Shell-Skript zu starten, das dann die Python startet. Nicht wirklich das, was ich mag, aber es ist so wie es ist ...

Claude
quelle
Vielen Dank für den Link zum Fehlerbericht. Gut bis jetzt ist es ein echter Bug. Ich fand eine andere Kupplung darum; Ich werde es hier posten.
halloleo
1

Das Problem ist, dass launchd eine andere PATH-Variable anfügt, anstatt die in der Umgebung zu ersetzen. Die meisten Programme verwenden, getenvdass immer das erste Vorkommen einer Variablen zurückgegeben wird. Stattdessen werden alle Umgebungsvariablen durchlaufen und als lokale Variablen importiert, wodurch vorherige Instanzen mit der letzten überschrieben werden.

Dies ist offensichtlich ein Fehler in launchd. An ein Programm übergebene Umgebungsvariablen sollten eindeutig sein.

StenSoft
quelle
1
Coole Hintergrundantwort! Ich schätze, du kommst nicht wirklich in Muscheln darum herum, oder gibt es das?
halloleo
@halloleo Sie können den Befehl so starten, wie sh -c 'YOUR ORIGINAL COMMAND'er durch die Shell geleitet wird, und den PATHSatz in launchd auswählen.
StenSoft