Comment définir des variables d'environnement à l'échelle du système sur OS X Mavericks

36

Nous avions l'habitude de /etc/environmentdéfinir des variables d'environnement à l'échelle du système sur Mountain Lion. Cependant, il semble que ce fichier ne soit plus lu.

Idéalement, la solution devrait s'appliquer à tous les utilisateurs, et nous en avons besoin pour fonctionner avec les sessions de console ssh. Nous avons donc besoin de ça pour fonctionner

ssh user@mavericks-machine 'echo $MY_ENV_VAR'

Jusqu'ici nous avons essayé:

  • /etc/launchd.conf

    Fonctionne pour tous les utilisateurs, mais ne s'applique qu'aux applications "fenêtrées", c'est-à-dire fonctionne dans Terminal, mais pas dans une session SSH.

  • ~/.profile, ~/.bash_profileEtc.

    Ne s'applique qu'aux coquillages

Aucune suggestion?

joerick
la source
Le fichier ( /etc/environment) n'est pas lu car ce n'est pas une norme intersystèmes, il fait simplement partie de la fonction Linux PAM. Mac OS X n'est pas Linux et n'utilise pas PAM, pas plus que d'autres systèmes d'exploitation à ma connaissance. Vous ne vous en êtes sorti que parce que vous étiez sous Linux, apparemment. Et oui, il est lu encore - par Linux ;-)
amn

Réponses:

18

Le bon fichier, avant Mavericks, était ~/.MacOSX/environment.plist. Ce n'est plus supporté.

Dans Darwin, et donc sous Mac OS X, il convient de les définir /etc/launchd.confpour les appliquer à tous les processus. s’il s’agit spécifiquement de shell utilisateur, utilisez plutôt les fichiers shell appropriés, en fonction du shell en question. Voir les pages de manuel launchd.confet launchctlpour plus.

Cela dit...

Si votre objectif est spécifiquement de voir ces applications appliquées aux sessions SSH, vous devez savoir que SSH, pour des raisons de sécurité, n'applique pas les variables d'environnement de cette manière. En fait, une session SSH reçoit normalement un ensemble beaucoup plus restrictif de variables d’environnement de la part du système d’exploitation, car ce n’est pas ce qu’on appelle un shell "de connexion" ou "interactif", elle est classée comme un shell "non interactif". (Voir man bashpour plus d'informations sur les types de shell.) La façon dont ssh traite les variables d'environnement est bien décrite dans la documentation et les pages de manuel ssh / sshd.

Pour ssh (qui est son propre shell, semblable à bash), les variables d'environnement de la session sont stockées en ~/.ssh/environmenttant qu'équivalent par utilisateur pour leur définition pour bash ou csh, etc. dans leurs fichiers de lancement correspondants. C’est probablement là que vous souhaitez définir vos variables ENV pour vos sessions SSH utilisateur, sans toutefois expliquer en détail la raison pour laquelle vous souhaitez attribuer des ENV au niveau global dans votre message d’origine, ce qui aurait été utile pour fournir une solution. Je vous suggèrerais de les définir explicitement pour chaque utilisateur afin de maintenir une sécurité appropriée pour chaque compte respectif, conformément aux meilleures pratiques en matière de privilèges et d'attributs les moins restrictifs.

Si, pour une raison quelconque, vous souhaitez ignorer ses implications pour la sécurité, définissez-le PermitUserEnvironmentdans vos config ssh. Notez que ceci est désactivé si UseLoginest activé. IMPORTANT: sachez que cela signifie que les comptes utilisateur configurés pour être utilisés en /bin/falsetant que shell - la méthode habituelle pour désactiver un compte utilisateur - peuvent désormais contourner cette restriction et devenir actifs, ce qui est dangereux. De nombreux comptes sont configurés pour utiliser /bin/falseleur shell comme attente de sécurité.

En bout de ligne, vous ne devriez pas faire cela globalement et attendre que ssh propage ENV pour des raisons de sécurité. En réalité, votre question demande délibérément comment vaincre plusieurs mécanismes existants pour des raisons de sécurité.

ColonelMode
la source
réponse très détaillée (+10) J'aime aussi la conclusion :) Bienvenue!
Ruskes
Je suggérerais qu'avec l'avertissement de sécurité, il peut en effet y avoir des raisons valables de le faire. Tout dépend de votre modèle de menace. Si vous configurez un groupe d’automates de test, il peut être judicieux de le faire.
uchuugaka
2
Selon stackoverflow.com/a/26311753/1081043 , /etc/launchd.confne fonctionne plus à partir de OSX 10.10 Yosemite.
Wisbucky
10

Si vous utilisez bash, la définition des variables d'environnement /etc/profiles'appliquera à tous les utilisateurs.

Du bashmanuel sur OS X Mavericks , avec mon emphase (cela n'a pas changé depuis les versions précédentes):

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l'option --login, il commence par lire et exécuter les commandes du fichier / etc / profile, si ce fichier existe. Après avoir lu ce fichier, il recherche ~ / .bash_profile, ~ / .bash_login et ~ / .profile, dans cet ordre, puis lit et exécute les commandes à partir de la première qui existe et est lisible.
...
Si bash est appelé avec le nom sh, il essaie de reproduire le plus fidèlement possible le comportement au démarrage des versions historiques de sh, tout en respectant le standard POSIX. Lorsqu'il est appelé en tant que shell de connexion active interactif interactif ou non interactif avec l'option --login, il tente d'abord de lire et d'exécuter des commandes à partir de / etc / profile. et ~ / .profile, dans cet ordre.

MK
la source
5

Ce que vous (et quiconque trouve cette question) cherchez presque certainement est le chemin suivant:

/private/etc/paths

Vous pouvez toujours placer vos modifications dans le /private/etc/paths.ddocument de configuration "chemins" par défaut du système principal, mais elles seront ensuite ajoutées à la fin de votre $PATHvariable. Par conséquent, si vous souhaitez ajouter des répertoires au début de $PATH(à remplacer les utilitaires système par défaut, par exemple), il vous suffira de modifier le /private/etc/pathsfichier principal lui-même et de les ajouter en haut de la liste. Par exemple, je le fais pour un dossier dans lequel je stocke une poignée de scripts que j'ai moi-même créés, ainsi que quelques utilitaires clés, tels quemozjpeg, que je veux que le système utilise toujours à la place des valeurs par défaut fournies (de cette façon, tous les fichiers jpeg enregistrés par pratiquement tous les programmes sont automatiquement compressés de 10% de plus que l'utilitaire habituel cjpeg du système les compresserait - I ' J'ai lu que la raison pour laquelle ce n'est pas le cas sur la plupart des systèmes, c'est parce que c'est beaucoup plus lent, mais lorsque vous parlez de 0,14 seconde au lieu de 0,02 seconde, le mot "plus lent d'un facteur 7" ne signifie pas grand-chose de rien ... en supposant que ce ne est pas un serveur, bien sûr). Je sais que beaucoup de gens vont probablement mettre en garde sur le "danger" potentiel de faire des modifications aussi profondes dans le système, mais je dirais que si vous cherchez une réponse comme celle-ci, vous en savez probablement assez pour traiter n'importe quel nom d'utilisateur. les conflits susceptibles de survenir à l'avenir,/private/etc/pathsvraiment les propage à tous les utilisateurs / logins / instances possibles - tous les programmes, shells, etc. utiliseront les chemins de ce fichier pour construire la base de leur $PATHvariable.

Pour être honnête, je suis assez surpris que personne d'autre ici n'ait encore mentionné cela. Tout ce fouillis avec launchd et les distractions liées aux utilisations spécifiques de SSH ... c'est la solution que recherchent tous ceux qui recherchent ce problème fondamental: la solution propre, directe et à la source, toujours opérationnelle.

À propos, au cas où vous vous le demanderiez, sur OS X, /etcc'est simplement un lien symbolique vers /private/etc, vous pouvez donc le faire aussi facilement sudo nano /etc/pathset aller au même endroit. Le chemin ci-dessus est simplement le chemin complet du fichier.

Jordan Smith
la source
2
À moins que quelque chose me manque, cela ne définira qu'une seule variable d'environnement à l'échelle du système - $PATH. Le PO semble être à la recherche d'une solution générique - définissant n'importe quel paramètre , p $EDITOR. Ex. , Etc.
John N
Même avec la sudocommande, dans macOS Sierra, je reçois une autorisation refusée si j'essaie de créer, en utilisant echoun nouveau fichier /private/etc/paths.dcontenant un ajout au chemin. Mais cela fonctionne pour créer d'abord le fichier, puis utiliser sudo mvpour déplacer le fichier /private/etc/paths.d.
murray
Cela a aidé. D'autres répertoires étaient en train d'être ajoutés à ma liste PATH malgré la configuration de $ PATH dans mon ~/.zshrc... le coupable était en fait /private/etc/pathset je devais mettre à jour ce fichier. Merci.
être le
1

J'ai eu un problème similaire, plus précisément, je n'avais ~/.bashrcpas été recherché lors de la connexion à ma machine via SSH. J'ai trouvé que la modification d'un paramètre de configuration pour SSHd avait fait l'affaire. Peut-être que votre problème réside également dans le démon SSH?

Modifiez le fichier de configuration du service SSH comme suit:

# /etc/sshd_config
PermitUserEnvironment yes

Puis redémarrez le service de connexion à distance dans Préférences Système> Partage.

De la sshd_configpage de manuel:

 PermitUserEnvironment
         Specifies whether ~/.ssh/environment and environment= options in
         ~/.ssh/authorized_keys are processed by sshd(8).  The default is
         ``no''.  Enabling environment processing may enable users to
         bypass access restrictions in some configurations using mecha-
         nisms such as LD_PRELOAD.

(Si cela peut aider, j'ai écrit comment j'ai testé cela sur mon wiki personnel )

RobM
la source
1

Si d'autres cherchent à définir des variables d'environnement pour des processus démarrés à partir d'une session de connexion graphique normale, vous pouvez utiliser /etc/launchd.conf. Pour ajouter par exemple /usr/local/binau chemin par défaut, exécutez

echo setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin|sudo tee -a /etc/launchd.conf

et redémarrez pour appliquer les modifications. Une autre façon d'appliquer les modifications consiste à exécuter launchctl</etc/launchd.conf;sudo launchctl</etc/launchd.confet à relancer les processus.

Lri
la source
/etc/launchd.conf n'est plus utilisé dans launchd.
uchuugaka
2
/etc/launchd.confn'est plus supporté depuis OSX 10.10 Yosemite
wisbucky le
0

Hmm ... À partir de Mac OS X 10.10.5 et probablement plus tôt, il man -s5 launchd.confnous dit: " launchd.conf is no longer respected by the system." J'ai trop de choses à faire pour mettre une variable factice dans le fichier et redémarrer pour voir si cela fonctionne vraiment ou pas après. tout, mais la documentation dit que cela ne devrait pas fonctionner.

Je suis sûr que ça ne va pas. Faites man launchctlet vous verrez: " The /etc/launchd.conf file is no longer consulted for subcommands to run during early boot time; this functionality was removed for security considerations."

Ce que vous pouvez faire est de mettre toutes les variables d’environnement que vous voulez être globales dans un fichier, peut-être appelé environmentcomme Linux, ou (si Apple décide de faire quelque chose avec ça plus tard - on ne sait jamais) environment.conf, comme je l’ai fait, puis source ceci via /etc/profile:

if [ -f /etc/environment.conf ]; then
   source /etc/environment.conf
fi

ou, si vous préférez le format compact:

if [ -f /etc/environment.conf ]; then . /etc/environment.conf; fi

Si vous utilisez un shell autre que bash et qu'il utilise la même syntaxe de paramétrage variable que bash (tout comme zsh, je pense), vous devrez également le source à partir du fichier rc de ce shell (par exemple /etc/zshrc). Si vous utilisez un shell qui utilise une syntaxe différente, par exemple tcsh, vous devrez soit conserver un fichier similaire pour ce shell et le générer à partir du fichier rc du système (par exemple /etc/csh.cshrcpour tcsh), ou, mieux encore, créer un script. qui le génère automatiquement, il vous suffit donc de modifier un fichier pour ajouter / modifier des variables. Ce n'est pas l'endroit pour un tel tutoriel; quelques secondes sur Google ont montré comment convertir les exportations de variable [t] csh en syntaxe bash, à l' adresse https://stackoverflow.com/questions/2710790/how-to-source-a-csh-script-in-bash-to -set-the-environment, donc il y a probablement quelque chose de disponible pour aller dans l'autre sens.

D'après mon expérience, Mac OS X s'éloigne de plus en plus du comportement prévisible des fichiers rc. En d'au moins 10,8, il ne semble plus à charger /etc/rc.common, /etc/rc.confou /etc/rc.<anything>, ni (depuis au moins 10.9) sera elle charge /etc/bash.bashrcpour les réservoirs non connectés interactifs (dont il devrait certainement être faites, tout comme il charge ~/.bashrcpour eux, encore, à partir de 10,10) . Encore une fois, Fink, MacPorts et Homebrew sont tous installés, donc l’un d’entre eux interfère avec le comportement par défaut du fichier point. YMMV.

S. McCandlish
la source
La question est pour les versions antérieures d'OS X, il y en aura d'autres, par exemple apple.stackexchange.com/questions/215932/… pour plus tard
user151019
Mon message s'adressait à la fois à Mavericks (10.9) et à 10.10. Si votre argument est que 10.10 est un sujet entièrement commenté dans un fil de discussion sur 10.9, je ne sais pas pourquoi vous m'avez dirigé vers un fil de discussion 10.11, où 10.10 serait également hors sujet (si le fil de discussion en question n'était pas invalide et fermé quand même). LOL.
S. McCandlish