In OSX Yosemite, perché posso impostare molte variabili di ambiente per le app GUI, ma non posso impostare la variabile PATH specifica


16

Dopo aver risolto i problemi PATH di OSX fino alla versione Mavericks, i problemi tornano in Yosemite !!!

Quindi voglio imitare la vecchia launch.conffunzionalità della nuova versione di Yosemite per Mac OSX 10.10, al fine di rendere disponibile la variabile d'ambiente PATH nelle app GUI come Carbon Emacs o RStudio . Ho usato la grande idea di ursa utente stackoverflow per impostare uno script shell che configura le variabili di ambiente tramite launchctl. (Vedi la sua risposta StackOverflow qui .) Funziona per la maggior parte delle variabili d'ambiente, ma non per la variabile PATH .

1. Che cosa ho fatto?

Prima ho scritto la /etc/environment.rcsceneggiatura come:

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"

Quindi ho creato i piani per launchd(elenchi di questi e di altri script citati nell'appendice di seguito). Poi li ho attivati ​​con

$ sudo launchctrl load ...

Quindi ho disabilitato l' path_helperutilità nel /etc/profilo del file di shell shell , in modo che non sovrascriva le environment.rcimpostazioni. E finalmente ho riavviato la macchina.

2. Qual è l'effetto?

Quando avvio Terminal le nuove variabili d'ambiente JAVA_HOMEe ENVIRONMENT_RCsono impostate in base environment.rc, ma PATH è impostato su

/ Usr / bin: bin /

Per essere sicuro, nessun bashfile init ha interferito nel modo in cui ho scritto un piccolo script Python (anche nell'appendice) per mostrare le variabili nell'ambiente corrente e lo eseguo direttamente facendo doppio clic su un wrapper Platypus . Anche in questo caso vengono impostate le nuove variabili, mentre PATH ha l'impostazione predefinita del sistema.

Quindi perché posso impostare altre variabili, ma non la variabile PATH? E come posso risolverlo in modo unificato ?

Aggiornare:

La situazione è molto sconcertante: la shell ( bashalmeno) in Terminal o Emacs raccoglierà il PERCORSO impostato tramite launchctl, ma le altre app della GUI non lo faranno. Ad esempio, lo script Python minimo menzionato direttamente chiamato Platypus non mostrerà la tua personalizzazione sentiero. E anche Emacs stesso non conosce il PERCORSO corretto: questo si nota ad esempio quando si emette il comando Emacs M-x ispell-buffer; lo strumento unix ispellche emacs tenta di chiamare non verrà trovato se si trova solo sul tuo percorso personalizzato.


Appendice

net.halloleo.environment.plist, il file di configurazione launchd 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, il file di configurazione launchd 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, il file di avvio di bash modificato:

# 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, lo script che mostra tutte le variabili di ambiente:

import os
print (os.environ)

Risposte:


3

PATH in Yosemite può e deve essere impostato nel file / etc / percorsi. Aggiungi il tuo percorso alla fine di questo file:

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

Lo script / etc / environment nel post originale fornisce supporto per la variabile PATH nelle applicazioni GUI (testato con Emacs).


5
Questo funziona solo per le shell che chiamano /usr/libexec/path_helperdurante il loro processo di inizializzazione. Le app GUI non ottengono il PERCORSO in base a /etc/paths- e ho chiesto specificamente sulle app GUI.
halloleo,

Ho aggiornato la risposta e / etc / environment script nel post originale
ursa,

Queste sono due risposte che stai dando - anche l'OP dice / etc / environment non funziona
user151019

@mark (1) dopo che questa domanda è stata sollevata, ho aggiornato / etc / environment, e ora supporta PATH. (2) la risposta qui è usare / etc / percorsi
ursa,

2
@mark Sì, e questo è esattamente il mio punto, problema e domanda: come posso impostare la variabile d'ambiente PATH delle app GUI se avviata tramite il Finder? Tuttavia, nessuna vera soluzione generale per questo in vista ...
halloleo,

2

Questo mi ha lasciato perplesso per molto tempo (beh, le ultime due ore). Alla fine mi sono imbattuto in questa segnalazione di bug, che sembra descrivere esattamente il mio problema (non sono sicuro di quale estensione sia correlata al tuo problema, ma sembra che ci sia un bug in Yosemite / launchd in combinazione con PATH e script come come pitone:

http://www.openradar.me/18945659

La soluzione sembra essere quella di avviare uno script di shell che avvia quindi il pitone. Non proprio quello che mi piace, ma è così ....


Grazie per il link alla segnalazione dei bug. Bene, adesso è un vero bug. Ho trovato un'altra frizione intorno ad esso; Lo posterò qui.
halloleo

1

Il problema è che launchd aggiunge un'altra variabile PATH invece di sostituire quella nell'ambiente. La maggior parte dei programmi utilizza getenvche restituisce sempre la prima occorrenza di una variabile, le shell invece eseguono l'iterazione attraverso tutte le variabili di ambiente e le importano come variabili locali sovrascrivendo così le istanze precedenti con l'ultima.

Questo è ovviamente un bug in launchd, le variabili di ambiente passate a un programma dovrebbero essere uniche.


1
Bella risposta di fondo! Immagino che il loro non sia un vero modo per aggirarlo nelle conchiglie, o c'è?
halloleo,

@halloleo Puoi lanciare il comando come sh -c 'YOUR ORIGINAL COMMAND'se lo passasse tramite shell, selezionando il PATHset in launchd.
StenSoft,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.