196 votes

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

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

Existe-t-il une autre solution pour définir de façon permanente les variables d'environnement ?

173voto

MortimerGoro Points 481

Créer un 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 plusieurs launchctl à l'intérieur du <string></string> bloc.

Le site plist s'activera 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 dans 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 "Réouvrir Windows lors de la reconnexion" est sélectionnée, il se peut que Windows rouvert ne voie pas les variables (elles sont peut-être ouvertes avant l'exécution de l'agent). De même, 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 sur El Capitan et Sierra. Cela doit être défini via 'launchctl config user path ...' et dans /etc/paths.

21 votes

Pas besoin de redémarrer ! Vous pouvez faire "launchctl start environment.plist" et redémarrer l'application dont vous avez besoin pour obtenir les nouvelles valeurs d'environnement ;)

1 votes

Cela ne fonctionnerait pas avec la variable PATH pour moi. Donc, en plus de cette approche pour définir d'autres variables, je définis la variable PATH dans mon ~/.bash_profile. Il est possible que cela ne fonctionne pas dans tous les cas, mais jusqu'à présent, je n'ai pas eu de problème.

0 votes

@djule5 Le PATH fonctionne pour moi, j'utilise cette ligne pour ajouter gradle au chemin : launchctl setenv PATH $PATH:/Applications/gradle/bin

65voto

ruario Points 191

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

Il est évident que vous ne voudrez pas faire cela à chaque fois que vous vous connecterez.

[ Modifier ] : Pour éviter cela, lancez AppleScript Editor Entrez une commande comme celle-ci :

do shell script "launchctl setenv variablename value"

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

Maintenant, sauvegardez ( + s ) comme Format de fichier : Application . Enfin, ouvrez System Settings Utilisateurs et groupes Articles de connexion et ajoutez votre nouvelle application.

[ Réponse originale ] : Pour contourner ce problème, placez toutes les variables que vous souhaitez définir dans un court script de l'interpréteur de commandes, puis jetez un coup d'œil à ce qui suit. réponse précédente sur comment exécuter un script sur MacOS login . De cette façon, le script sera invoqué lorsque l'utilisateur se connectera.

[ Modifier ] : Aucune de ces deux solutions n'est parfaite, car les variables ne seront définies que pour cet élément. spécifique mais j'espère/présume que c'est tout ce dont vous avez besoin.

Si vous avez plusieurs utilisateurs, vous pouvez soit définir manuellement un groupe d'utilisateurs. Elément de connexion pour chacun d'entre eux ou placer une copie de com.user.loginscript.plist dans chacun de leurs locaux Bibliothèque/LaunchAgents répertoires, pointant vers le même shell script.

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

[ Autres modifications ] : Un utilisateur ci-dessous mentionne 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 que vous devrez redémarrer les applications pour que cela prenne effet. De plus, si vous définissez des variables dans le terminal via ~/.profil o ~/.bash_profile ils remplaceront les éléments définis par launchctl setenv para applications lancées à partir de l'interpréteur de commandes .

5 votes

D'après ce que je sais, l'un des inconvénients de cette technique est que la ou les variables ne seront pas définies pour les autres applications lancées lors de la connexion. Ainsi, par exemple, si vous ouvrez Terminal, la variable sera définie, mais si vous vous déconnectez et vous reconnectez, en faisant redémarrer automatiquement Terminal, la variable ne sera pas définie...

0 votes

J'ai essayé cette solution et cela n'a pas fonctionné pour moi non plus. Mais je m'attends précisément à ce que mon IDE Java (IntelliJ) prenne en compte mes modifications de chemin et ce n'est pas le cas. Tout fonctionne parfaitement à partir du terminal. Il s'agit peut-être d'un bogue dans IntelliJ. C'est quand même frustrant qu'Apple ait supprimé cette fonctionnalité. J'ai appelé Apple et ils n'ont pas été très utiles.

0 votes

Cela fonctionne pour moi, mais savez-vous comment faire pour ajouter également les variables d'environnement à sudo ?

21voto

ursa Points 27

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 la 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 permettant de 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 des utilisateurs de 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 devons 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 du système : /etc/environment
  2. Mise à jour automatique et instantanée des variables d'environnement après modification du fichier /etc/environnement - il suffit de relancer votre application.

Questions / problèmes :

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

  • soit se connecter deux fois : connexion => déconnexion => connexion
  • ou fermer et rouvrir les applications manuellement, où les variables d'environnement doivent être prises en compte.
  • ou n'utilisez PAS la fonction "Rouvrir les fenêtres lors de la reconnexion".

Cela se produit parce qu'Apple refuse l'ordre explicite des services chargés, de sorte que les variables env sont enregistrées en parallèle avec le traitement de la "file d'attente de réouverture".

Mais en fait, je ne redémarre mon système que plusieurs fois par an (lors de grosses mises à jour), donc ce n'est pas un gros problème.

0 votes

Excellente idée. Je l'ai essayé et cela fonctionne pour la plupart des variables d'environnement (comme JAVA_HOME ), mais pas pour le PATH (voir ma question sur la demande différente ).

4 votes

PATH doit être défini dans le fichier /etc/paths. Ajoutez simplement votre chemin personnalisé à la fin de ce fichier.

0 votes

Je ne suis pas très familier avec launchd Mais ne serait-il pas possible de charger ces démons au démarrage (c'est-à-dire avant la connexion) ? Cela devrait contourner tous les problèmes que vous mentionnez.

8voto

aax Points 28

Cité dans

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

Après de longues délibérations, les ingénieurs ont supprimé cette fonctionnalité. Le fichier /etc/launchd.conf a été intentionnellement supprimé pour des raisons de sécurité. Comme solution de contournement, vous pouvez exécuter launchctl limit comme Root au début du démarrage, peut-être à partir d'une 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

1 votes

Pouvez-vous expliquer cela un peu plus ? Je ne vois pas en quoi l'option "Résoudre le problème" est liée au problème initial !

0 votes

Ce n'est pas l'OP, mais je pense que l'essentiel ici est : mettez ce plist dans /Library/LaunchDaemons et au lieu de dire launchctl pour exécuter le limit et dites-lui d'exécuter la commande setenv avec PATH et une chaîne de chemin comme arguments. launchd devrait le capter automatiquement au démarrage et s'auto-modifier presque immédiatement.

5 votes

La copie du xml est incomplète. La ligne doctype devrait se lire <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

2voto

Baptiste Points 66

Ce qui a fonctionné pour moi (inspiré des remerciements d'aax) :

Collez ceci dans /Bibliothèque/LaunchDaemons/com.apple.launchd.limit.plist puis redémarrer :

<?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, pas à pas :

  • Terminal de lancement
  • Type sudo su puis entrez votre mot de passe pour vous connecter en tant que Root
  • Type vi /Library/LaunchDaemons/com.apple.launchd.limit.plist
  • Une fois dans l'éditeur vi, appuyez sur la touche i pour entrer en mode insertion puis coller le contenu exact du code ci-dessus ( +v ). Cela forcera la limite à 16384 fichiers par processus et 16384 fichiers au total.
  • Sauvegardez votre fichier et cessez d'utiliser esc puis :wq
  • Redémarrez votre système, et vérifiez qu'il fonctionne en utilisant la commande launchctl limit

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

10 votes

Quel est le rapport entre cette solution et la définition de variables d'environnement ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X