web-dev-qa-db-fra.com

La définition de variables d’environnement via launchd.conf ne fonctionne plus sous OS X Yosemite / El Capitan / macOS Sierra / Mojave?

Il semble que le launchd.conf ne charge plus ma variable d'environnement. Quelqu'un a-t-il remarqué cela?

Existe-t-il une autre solution pour définir en permanence des variables d'environnement?

185
Tosh

Créez un fichier environment.plist dans ~/Library/LaunchAgents/ avec ce contenu:

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

Vous pouvez ajouter de nombreuses commandes launchctl à l'intérieur du bloc <string></string>.

La plist s'active après le redémarrage du système. Vous pouvez également utiliser launchctl load ~/Library/LaunchAgents/environment.plist pour le lancer immédiatement.

[Edit]

La même solution fonctionne aussi à El Capitan.

Xcode 7.0+ n'évalue pas les variables d'environnement par défaut. L'ancien comportement peut être activé avec cette commande:

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

[Edit]

Il y a quelques situations où cela ne fonctionne pas tout à fait. Si l'ordinateur est redémarré et que l'option "Rouvrir les fenêtres lors de la connexion" est sélectionnée, il est possible que les fenêtres rouvertes ne voient pas les variables (elles sont peut-être ouvertes avant que l'agent soit exécuté). De plus, si vous vous connectez via ssh, les variables ne seront pas définies (vous devrez donc les définir dans ~/.bash_profile). Enfin, cela ne semble pas fonctionner pour PATH à El Capitan et à Sierra. Cela doit être défini via 'launchctl config user path ...' et dans/etc/path.

151
MortimerGoro

[ Réponse originale ]: Vous pouvez toujours utiliser launchctl setenv variablename value pour définir une variable afin qu'elle soit prise en compte par toutes les applications (applications graphiques démarrées via le Dock ou Spotlight, en plus de celles lancées via le terminal).

Évidemment, vous ne voudrez pas faire cela à chaque fois que vous vous connectez.

[ Edit ]: pour éviter cela, lancez AppleScript Editor, entrez une commande comme celle-ci:

do Shell script "launchctl setenv variablename value"

(Utilisez plusieurs lignes si vous souhaitez définir plusieurs variables)

Enregistrez maintenant ( + s) sous Format de fichier: Application . Enfin, ouvrez System Settings Utilisateurs et groupes Ouvrez une session et ajoutez votre nouvelle application.

[ Réponse originale ]: Pour contourner cet endroit, toutes les variables que vous souhaitez définir dans un court script de shell, puis jetez un coup d'œil à ceci réponse précédente sur la manière d'exécuter un script sur une connexion MacOS . De cette façon, le script sera appelé lorsque l'utilisateur se connectera.

[ Edit ]: Aucune solution n'est parfaite car les variables ne seront définies que pour cet utilisateur spécifique , mais J'espère/devine que c'est peut-être tout ce dont vous avez besoin.

Si vous avez plusieurs utilisateurs, vous pouvez soit définir manuellement un élément de connexion pour chacun d'eux, soit placer une copie de com.user.loginscript.plist dans chacun de leurs répertoires local Library/LaunchAgents , pointant vers le même script shell.

Certes, aucune de ces solutions de contournement n’est aussi pratique que /etc/launchd.conf .

[ Modification ultérieure ]: Un utilisateur ci-dessous indique que cela n'a pas fonctionné pour lui. Cependant, j'ai testé sur plusieurs machines Yosemite et cela fonctionne pour moi. Si vous rencontrez un problème, rappelez-vous qu'il vous faudra redémarrer les applications pour que cela prenne effet. De plus, si vous définissez des variables dans le terminal via ~/.profile ou ~/.bash_profile , elles remplaceront les éléments définis via launchctl setenv pour les applications lancées à partir du shell .

63
ruario

Il est possible de définir des variables d’environnement sur Mac OS X 10.10 Yosemite avec 3 fichiers + 2 commandes.

Fichier principal avec définition des variables d'environnement:

$ 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"

Définition du service pour charger les variables d'environnement pour les applications utilisateur (terminal, 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 même définition de service pour les applications utilisateur 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>

Et enfin, nous devrions enregistrer ces services:

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

Ce que nous obtenons:

  1. Le seul endroit où déclarer les variables d'environnement système:/etc/environment
  2. Mise à jour automatique instantanée des variables d'environnement après modification du fichier/etc/environment - il suffit de relancer votre application

Problèmes/problèmes:

Afin que vos variables env soient correctement prises par les applications après le redémarrage du système vous aurez besoin de:

  • soit vous connecter deux fois: login => logout => login
  • ou fermez et rouvrez les applications manuellement, où les variables env doivent être prises
  • ou n'utilisez PAS la fonctionnalité "Rouvrir les fenêtres lors de la reconnexion".

Cela est dû à Apple qui refuse l'ordre explicite des services chargés. Par conséquent, les variables env sont enregistrées en parallèle avec le traitement de la "file d'attente de réouverture".

Mais en réalité, je ne redémarre mon système que plusieurs fois par an (sur de grosses mises à jour), ce n'est donc pas grave.

21
ursa

Cité de

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

Après de longues délibérations, l’ingénierie a supprimé cette fonctionnalité. Le fichier /etc/launchd.conf a été supprimé intentionnellement pour des raisons de sécurité. Pour contourner le problème, vous pouvez exécuter launchctl limit en tant que root au début du démarrage, par exemple à partir de LaunchDaemon. (...)

Solution:

Mettez le code dans /Library/LaunchDaemons/com.Apple.launchd.limit.plist par 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
6
aax

Voici les commandes pour restaurer l'ancien comportement:

# 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

Vous pouvez maintenant spécifier des commandes telles que setenv Java_HOME /Library/Java/Home dans /etc/launchd.conf.

Vérifié sur El Capitan.

3
yanchenko

Qu'est-ce qui a fonctionné pour moi (inspiré des remerciements d'Aax):

Collez ceci dans / Library/LaunchDaemons/com.Apple.launchd.limit.plist puis redémarrez:

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

Si vous en avez besoin étape par étape:

  • Terminal de lancement
  • Tapez Sudo s puis entrez votre mot de passe pour vous connecter en tant que root
  • Tapez vi /Library/LaunchDaemons/com.Apple.launchd.limit.plist
  • Lorsque vous êtes dans l'éditeur vi, appuyez sur la touche i pour passer en mode insertion, puis collez le contenu du code exact ci-dessus (⌘+v). Cela forcera la limite à 16384 fichiers par processus et à 16384 fichiers au total
  • Enregistrez votre fichier et quittez avec esc puis :wq
  • Redémarrez votre système et vérifiez qu'il fonctionne à l'aide de la commande launchctl limit

J'espère que cela vous a aidé.

2
Baptiste

Vous pouvez essayer https://github.com/ersiner/osx-env-sync . Il gère à la fois les applications en ligne de commande et les applications graphiques à partir d'une source unique et fonctionne avec la dernière version de OS X (Yosemite).

Vous pouvez utiliser des substitutions de chemins et d'autres astuces de Shell, car ce que vous écrivez est un script bash régulier à obtenir par bash en premier lieu. Pas de restrictions .. (Consultez la documentation osx-env-sync et vous comprendrez comment il y parvient.)

J'ai répondu à une question similaire ici où vous en trouverez plus.

2
Ersin Er