L'impostazione delle variabili di ambiente tramite launchd.conf non funziona più in OS X Yosemite / El Capitan / macOS Sierra / Mojave?


190

Sembra launchd.confche non carichi più la mia variabile d'ambiente. Qualcun altro l'ha notato?

Esiste un'altra soluzione per impostare in modo permanente le variabili di ambiente?


Funziona e si rende disponibile nell'applicazione ma non nel terminale
Chang Zhao,

Risposte:


159

Crea un environment.plistfile ~/Library/LaunchAgents/con questo contenuto:

<?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>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>
    launchctl setenv PRODUCTS_PATH /Users/mortimer/Projects/my_products
    launchctl setenv ANDROID_NDK_HOME /Applications/android-ndk
    launchctl setenv PATH $PATH:/Applications/gradle/bin
    </string>

  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Puoi aggiungere molti launchctlcomandi all'interno del <string></string>blocco.

Si plistattiverà dopo il riavvio del sistema. Puoi anche usarlo launchctl load ~/Library/LaunchAgents/environment.plistper avviarlo immediatamente.

[Modificare]

La stessa soluzione funziona anche a El Capitan.

Xcode 7.0+ non valuta le variabili di ambiente per impostazione predefinita. Il vecchio comportamento può essere abilitato con questo comando:

defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool NO

[Modificare]

Ci sono un paio di situazioni in cui questo non funziona del tutto. Se il computer viene riavviato e viene selezionata l'opzione "Riapri finestre quando si riconnette", le finestre riaperte potrebbero non visualizzare le variabili (forse vengono aperte prima dell'esecuzione dell'agente). Inoltre, se accedi tramite ssh, le variabili non verranno impostate (quindi dovrai impostarle in ~ / .bash_profile). Infine, questo non sembra funzionare per PATH su El Capitan e Sierra. Questo deve essere impostato tramite 'launchctl config user path ...' e in / etc / percorsi.


20
Non è necessario riavviare! Puoi fare "launchctl start environment.plist" e riavviare l'app di cui hai bisogno per ottenere i nuovi env vars;)
hasvn

1
Questo non funzionerebbe con la variabile PATH per me. Quindi oltre a questo approccio per impostare altre variabili, ho impostato la variabile PATH nel mio ~ / .bash_profile. Questo potrebbe non funzionare per tutti i casi, ma finora non ho avuto problemi.
djule5,

6
Capito: per funzionare senza riavvio, dovrebbe essere "launchctl load environment.plist", non iniziare
Dave Hartnoll,

2
Ah sì. Niente come un'impostazione di configurazione oscura che appare esattamente 9 volte in tutta Internet (google UseSanitizedBuildSystemEnvironment).
Ohad Schneider,

2
Funziona anche su Sierra
Shwouchk,

64

[ Risposta originale ]: è ancora possibile utilizzare launchctl setenv variablename valueper impostare una variabile in modo che venga rilevata da tutte le applicazioni (applicazioni grafiche avviate tramite Dock o Spotlight, oltre a quelle avviate tramite il terminale).

Ovviamente non vorrai farlo ogni volta che accedi.

[ Modifica ]: per evitarlo, avvia AppleScript Editor, inserisci un comando come questo:

do shell script "launchctl setenv variablename value"

(Utilizzare più righe se si desidera impostare più variabili)

Ora salva ( + s) come Formato file: Applicazione . Infine apri System SettingsUtenti e gruppiElementi di accesso e aggiungi la tua nuova applicazione.

[ Risposta originale ]: per aggirare questo posto tutte le variabili che si desidera definire in uno script di shell corta, quindi dare un'occhiata a questa risposta precedente su come eseguire uno script con l'accesso a MacOS . In questo modo lo script verrà invocato quando l'utente accede.

[ Modifica ]: nessuna delle due soluzioni è perfetta in quanto le variabili verranno impostate solo per quell'utente specifico, ma spero / indovino che potrebbe essere tutto ciò di cui hai bisogno.

Se si dispone di più utenti, è possibile impostare manualmente un elemento di accesso per ciascuno di essi oppure posizionare una copia di com.user.loginscript.plist in ciascuna delle directory Library / LaunchAgents locali , puntando allo stesso script shell.

Concesso, nessuna di queste soluzioni alternative è conveniente come /etc/launchd.conf .

[ Ulteriore modifica ]: un utente di seguito menziona che questo non ha funzionato per lui. Tuttavia, ho testato su più macchine Yosemite e funziona per me. Se si riscontra un problema, ricordare che sarà necessario riavviare le applicazioni affinché ciò abbia effetto. Inoltre, se si impostano le variabili nel terminale tramite ~ / .profile o ~ / .bash_profile , sovrascriveranno le cose impostate tramite launchctl setenv per le applicazioni avviate dalla shell .


5
Per quanto ne so, uno svantaggio di questa tecnica è che le variabili non verranno impostate per altre applicazioni avviate al momento dell'accesso. Quindi, ad esempio, se apri Terminale, la variabile verrà impostata, ma se ti disconnetti e
riaccedi

Ho provato questa soluzione e non ha funzionato neanche per me. Ma mi aspetto specificamente che il mio IDE Java (IntelliJ) rilevi le modifiche del mio percorso e non lo è. Tutto funziona bene dal terminale. Potrebbe essere un bug in IntelliJ. Ancora frustrante che Apple abbia rimosso questa funzionalità. Ho chiamato Apple e non sono stati molto utili.
Jason,

Questo funziona per me, ma sai cosa fare per aggiungere anche le variabili d'ambiente a sudo?
etiennenoel,

2
Funzionerà in generale, tuttavia c'è un bug in Yosemite (almeno 10.10.0 e 10.10.1) in cui l'impostazione di $ PATH non funziona in questo modo. Apple è a conoscenza del bug. Attualmente (dal 10.10.1) non esiste un modo noto per impostare un $ PATH a livello di sistema per le app della GUI.
TJ Luoma,

3
Dopo aver utilizzato uno dei metodi sopra menzionati e aver riavviato il laptop - Assicurati di riaprire esplicitamente le applicazioni (come iTerm, terminal, Eclipse, IDEA o qualunque cosa tu stia utilizzando). Se non li riavvii esplicitamente e Se durante il riavvio di OSx la casella di controllo è stata selezionata su "Riavvia le finestre quando accedi nuovamente" (che è l'impostazione predefinita) - quei programmi non leggeranno le nuove variabili di ambiente.
Ha funzionato il

21

È possibile impostare variabili di ambiente su Mac OS X 10.10 Yosemite con 3 file + 2 comandi.

File principale con definizione delle variabili di ambiente:

$ ls -la /etc/environment 
-r-xr-xr-x  1 root  wheel  369 Oct 21 04:42 /etc/environment
$ cat /etc/environment
#!/bin/sh

set -e

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - start"

launchctl setenv JAVA_HOME      /usr/local/jdk1.7
launchctl setenv MAVEN_HOME     /opt/local/share/java/maven3

if [ -x /usr/libexec/path_helper ]; then
    export PATH=""
    eval `/usr/libexec/path_helper -s`
    launchctl setenv PATH $PATH
fi

osascript -e 'tell app "Dock" to quit'

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - complete"

Definizione del servizio per caricare le variabili di ambiente per le applicazioni utente (terminale, IDE, ...):

$ ls -la /Library/LaunchAgents/environment.user.plist
-rw-------  1 root  wheel  504 Oct 21 04:37 /Library/LaunchAgents/environment.user.plist
$ sudo cat /Library/LaunchAgents/environment.user.plist
<?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>Label</key>
    <string>environment.user</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

La stessa definizione di servizio per le applicazioni utente root:

$ ls -la /Library/LaunchDaemons/environment.plist
-rw-------  1 root  wheel  499 Oct 21 04:38 /Library/LaunchDaemons/environment.plist
$ sudo cat /Library/LaunchDaemons/environment.plist
<?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>Label</key>
    <string>environment</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

E infine dovremmo registrare questi servizi:

$ launchctl load -w /Library/LaunchAgents/environment.user.plist
$ sudo launchctl load -w /Library/LaunchDaemons/environment.plist

Cosa otteniamo:

  1. L'unico posto in cui dichiarare le variabili di ambiente di sistema: / etc / environment
  2. Aggiornamento automatico istantaneo delle variabili di ambiente dopo la modifica del file / etc / environment: è sufficiente riavviare l'applicazione

Problemi / problemi:

Per far sì che le variabili env siano state prese correttamente dalle applicazioni dopo il riavvio del sistema , sarà necessario:

  • o accedi due volte: login => logout => login
  • o chiudi e riapri le applicazioni manualmente, dove dovrebbero essere prese le variabili env
  • o NON utilizzare la funzione "Riapri le finestre quando si accede nuovamente".

Ciò accade perché Apple nega l'ordinamento esplicito dei servizi caricati, quindi le variabili env vengono registrate parallelamente all'elaborazione della "coda di riapertura".

Ma in realtà, riavvio il mio sistema solo più volte all'anno (su grandi aggiornamenti), quindi non è un grosso problema.


Grande idea. L'ho provato e funziona per la maggior parte delle variabili d'ambiente (come JAVA_HOME), ma non per la PATHvariabile (vedi la mia domanda su chiedere diverso ).
halloleo,

4
PATH dovrebbe essere impostato con il file / etc / percorsi. Aggiungi il tuo percorso personalizzato alla fine di questo file.
ursa,

Non ne ho familiarità launchd, ma non sarebbe possibile caricare quei demoni all'avvio (cioè prima dell'accesso)? Ciò dovrebbe eludere tutte le questioni che menzioni.
Egon,

Adoro l'approccio sopra ma ho un problema strano da gestire. Dopo il riavvio di un genet VARNAME mi restituisce il valore corretto ma echo $ VARNAME non restituisce nulla. Quale potrebbe essere una ragione per questo? L'ho pubblicato anche su stackoverflow.com/questions/27045137/… e spero che chiunque qui abbia un'idea
ctp

Assicurarsi che i permessi sui file di / etc / environment siano come sopra descritti.
imanuelcostigan,

6

Citato da

Apple Developer Relations 10-Oct-2014 09:12 PM

Dopo molte discussioni, l'ingegneria ha rimosso questa funzione. Il file è /etc/launchd.confstato rimosso intenzionalmente per motivi di sicurezza. Per ovviare al problema, è possibile eseguire launchctl limitcome root all'inizio durante l'avvio, forse da a LaunchDaemon. (...)

Soluzione:

Inserisci il codice in /Library/LaunchDaemons/com.apple.launchd.limit.plistda bash-script:

#!/bin/bash

echo '<?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>Label</key>
        <string>eicar</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/launchctl</string>
                <string>limit</string>
                <string>core</string>
                <string>unlimited</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceIPC</key>
        <false/>
</dict>
</plist>' | sudo tee /Library/LaunchDaemons/com.apple.launchd.limit.plist

1
Puoi spiegarlo un po 'di più? Non riesco a capire in che modo "Risolvi problema" si collega al problema iniziale!
Nick H247,

Non l'OP, ma penso che l'essenza qui sia: inserisci questo plist /Library/LaunchDaemonse, invece di dire launchctldi eseguire il limitcomando, digli di eseguire il setenvcomando con PATHuna stringa di percorso come argomenti. launchddovrebbe prenderlo automaticamente all'avvio e ottenere una sorta di auto-modifica quasi immediatamente.
Laird Nelson,

5
Il file XML viene copiato in modo incompleto. La riga del doctype dovrebbe essere<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
UloPe,

6
@aax quale parte di quel plist imposta effettivamente una variabile d'ambiente?
HairOfTheDog,

3

Ecco i comandi per ripristinare il vecchio comportamento:

# create a script that calls launchctl iterating through /etc/launchd.conf
echo '#!/bin/sh

while read line || [[ -n $line ]] ; do launchctl $line ; done < /etc/launchd.conf;
' > /usr/local/bin/launchd.conf.sh

# make it executable
chmod +x /usr/local/bin/launchd.conf.sh

# launch the script at startup
echo '<?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>Label</key>
  <string>launchd.conf</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>/usr/local/bin/launchd.conf.sh</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
' > /Library/LaunchAgents/launchd.conf.plist

Ora puoi specificare comandi come setenv JAVA_HOME /Library/Java/Homein /etc/launchd.conf.

Controllato su El Capitan.


2

Cosa ha funzionato per me (ispirato dai ringraziamenti di aax):

Incollalo in /Library/LaunchDaemons/com.apple.launchd.limit.plist quindi riavvia:

<?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>Label</key>
  <string>eicar</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>limit</string>
    <string>maxfiles</string>
    <string>16384</string>
    <string>16384</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

Se ne hai bisogno passo dopo passo:

  • Avvia terminale
  • Digita sudo su quindi inserisci la password per accedere come root
  • Digitare vi /Library/LaunchDaemons/com.apple.launchd.limit.plist
  • Nell'editor vi, premere il tasto i per accedere alla modalità di inserimento, quindi incollare il contenuto esatto del codice sopra ( ⌘+v). Ciò imporrà il limite a 16384 file per processo e 16384 file totali
  • Salvare il file e uscire usando escquindi:wq
  • Riavviare il sistema e verificare che funzioni utilizzando il comando launchctl limit

Spero che questo ti abbia aiutato.


10
Che cosa ha a che fare questa soluzione con l'impostazione delle variabili d'ambiente?
HairOfTheDog,

2

Puoi provare https://github.com/ersiner/osx-env-sync . Gestisce entrambe le app della riga di comando e della GUI da un'unica fonte e funziona con l' ultima versione di OS X (Yosemite).

È possibile utilizzare le sostituzioni di percorso e altri trucchi della shell poiché ciò che si scrive è un normale script bash che deve essere originariamente fornito da bash. Nessuna restrizione .. (Controlla la documentazione di osx-env-sync e capirai come ci riesce.)

Ho risposto a una domanda simile qui dove troverai di più.


-3

La soluzione è aggiungere la tua variabile a /etc/profile. Quindi tutto funziona come previsto! Ovviamente DEVI farlo come utente root con sudo nano / etc / profile. Se lo modifichi in qualsiasi altro modo il sistema si lamenterà di un profilo / etc / danneggiato, anche se cambi i permessi in root.


7
L'aggiunta di variabili d'ambiente al profilo è molto inferiore poiché influisce solo sui processi di shell.
UloPe,

-5

Ho aggiunto le variabili nel ~ / .bash_profile nel modo seguente. Al termine, riavviare / disconnettersi e accedere

export M2_HOME=/Users/robin/softwares/apache-maven-3.2.3
export ANT_HOME=/Users/robin/softwares/apache-ant-1.9.4
launchctl setenv M2_HOME $M2_HOME
launchctl setenv ANT_HOME $ANT_HOME
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/robin/softwares/apache-maven-3.2.3/bin:/Users/robin/softwares/apache-ant-1.9.4/bin
launchctl setenv PATH $PATH

NOTA: senza riavviare / disconnettersi e accedere è possibile applicare queste modifiche utilizzando;

source ~/.bash_profile

Si noti che non è necessario disconnettersi e riconnettersi. Utilizzare semplicemente il comando source, ad esempio source .bash_profile.
Michael,

2
Inoltre, il problema con questo metodo è che devi ancora aprire un terminale prima che le variabili di ambiente siano disponibili. Meglio fare ciò che è nella prima risposta in modo che siano disponibili senza dover aprire un terminale.
Michael,

1
Questo non funziona con le app caricate tramite SpotLight. stackoverflow.com/questions/135688/…
Rasika Perera

1
L'uso dei file di configurazione di bash è di aiuto limitato poiché presume che tu abbia sempre bash come un antenato del processo che è l'ambiente che stai cercando di attuare. Spotlight, il finder, emacs, xcode, cronjobs, agenti launchd, qualsiasi IDE, browser di controllo del codice sorgente, ecc. Ecc. Non avranno tutti bash come antenati. L'unico processo che può estendersi in modo coerente è l'avvio.
Ben Hyde,
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.