Como definir variáveis ​​de ambiente em todo o sistema no OS X Mavericks


36

Costumávamos usar /etc/environmentpara definir variáveis ​​de ambiente em todo o sistema no Mountain Lion. No entanto, parece que este arquivo não é mais lido.

Idealmente, a solução deve ser aplicada a todos os usuários, e precisamos que ela funcione com as sessões do console ssh. Então, precisamos que isso funcione

ssh user@mavericks-machine 'echo $MY_ENV_VAR'

Até agora, tentamos:

  • /etc/launchd.conf

    Funciona para todos os usuários, mas somente se aplica a aplicativos 'em janela', ou seja, funciona no Terminal, mas não em uma sessão ssh.

  • ~/.profile, ~/.bash_profileEtc.

    Aplica-se apenas a conchas

Alguma sugestão?


O arquivo ( /etc/environment) não é lido porque não é um padrão entre sistemas - é apenas parte do recurso PAM do Linux. O Mac OS X não é Linux e não usa PAM, nem outros sistemas operacionais, que eu saiba. Você só conseguiu se safar porque estava no Linux, aparentemente. E sim, ele ainda é lido - pelo Linux ;-)
amn

Respostas:


18

O arquivo correto, antes do Mavericks, era ~/.MacOSX/environment.plist. Isso não é mais suportado.

Em Darwin e, portanto, no Mac OS X, o local apropriado para defini-las é /etc/launchd.confaplicar a todos os processos; se estiver relacionado especificamente aos shells do usuário, use os arquivos de shell apropriados, dependendo do shell em questão. Veja as páginas de manual launchd.confe launchctlpara mais.

Dito isto...

Se seu objetivo é especificamente vê-los aplicados a sessões ssh, você deve estar ciente de que o ssh, por motivos de segurança, não aplica variáveis ​​de ambiente dessa maneira. De fato, uma sessão ssh normalmente recebe um conjunto muito mais restritivo de variáveis ​​de ambiente do sistema operacional, pois não é o que é conhecido como shell de "login" ou "interativo", mas classificado como um shell "não interativo". (Veja man bashmais sobre os tipos de shell.) A maneira como o ssh lida com variáveis ​​de ambiente é bem abordada nos documentos e páginas de manual do ssh / sshd.

Para ssh - que é seu próprio shell, semelhante ao bash - as variáveis ​​de ambiente da sessão são armazenadas ~/.ssh/environmentcomo o equivalente por usuário de defini-las para bash ou csh, etc. em seus arquivos de inicialização relevantes. Provavelmente é aqui que você deseja definir suas variáveis ​​ENV para as sessões ssh do usuário, embora você não especifique por que deseja atribuir ENVs globalmente em sua postagem original, o que seria útil para fornecer uma solução. Eu sugiro que você os defina explicitamente em uma base por usuário para manter a segurança adequada com base em cada conta respectiva, seguindo as práticas recomendadas menos restritivas de privilégios / atributos.

Se, por algum motivo, você deseja ignorar as implicações de segurança disso, defina PermitUserEnvironmentsuas configurações ssh. Observe que isso está desativado se UseLoginestiver ativado. IMPORTANTE: Entenda que isso significa que as contas de usuário definidas para serem usadas /bin/falsecomo shell - o método típico para desativar uma conta de usuário - agora podem potencialmente contornar essa restrição e agora podem se tornar ativas, o que é perigoso. Muitas contas estão definidas para usar /bin/falsecomo shell como uma expectativa de segurança.

Resumindo, você não deve fazer isso globalmente e esperar que o ssh propague o ENV por motivos de segurança. Sua pergunta é, efetivamente, propositalmente perguntando como derrotar vários mecanismos existentes por motivos de segurança.


resposta muito detalhada (+10) Também gosto da conclusão :) Bem-vindo!
Ruskes

Eu sugeriria que, com a ressalva de segurança, pode realmente haver razões válidas para fazer isso. Tudo depende do seu modelo de ameaça. Se você estiver configurando um grupo de máquinas de automação de teste, pode fazer sentido fazer isso.
Uchuugaka

2
De acordo com stackoverflow.com/a/26311753/1081043 , /etc/launchd.confnão funciona mais a partir do OSX 10.10 Yosemite.
wisbucky

10

Se você estiver usando bash, a configuração das variáveis ​​de ambiente /etc/profileserá aplicada a todos os usuários.

Do bashmanual no OS X Mavericks , com minha ênfase (isso não mudou nas versões anteriores):

Quando o bash é chamado como um shell de login interativo ou como um shell não interativo com a opção --login, ele primeiro lê e executa comandos do arquivo / etc / profile, se esse arquivo existir. Depois de ler esse arquivo, ele procura ~ / .bash_profile, ~ / .bash_login e ~ / .profile, nessa ordem, e lê e executa comandos do primeiro que existe e é legível.
...
Se o bash for chamado com o nome sh, ele tentará imitar o comportamento de inicialização das versões históricas do sh o mais próximo possível, além de estar em conformidade com o padrão POSIX. Quando chamado como um shell de login ativo interativo interativo ou um shell não interativo com a opção --login, ele primeiro tenta ler e executar comandos em / etc / profile e ~ / .profile, nessa ordem.


5

O que você (e qualquer outra pessoa que encontra essa pergunta) está quase certamente procurando é o seguinte caminho:

/private/etc/paths

Você sempre pode colocar suas edições no /private/etc/paths.dse desejar evitar alterar o documento de configuração "caminhos" padrão do sistema principal, mas elas serão anexadas ao final da sua $PATHvariável, portanto, se você quiser adicionar diretórios na frente de $PATH(para sobrepor os utilitários padrão do sistema, por exemplo), basta editar o /private/etc/pathspróprio arquivo principal e adicioná-los ao topo da lista. Por exemplo, faço isso para uma pasta na qual armazeno alguns scripts criados por mim, além de alguns utilitários importantes, comomozjpeg, que eu quero que o sistema sempre use em vez dos padrões que ele vem (dessa forma, todos os arquivos jpeg salvos por praticamente qualquer programa são compactados automaticamente em até 10% mais do que o utilitário cjpeg normal do sistema os comprimiria - eu ' você leu que a razão de não ser o padrão na maioria dos sistemas é porque é muito mais lento, mas quando você está falando algo em torno de 0,14 segundos em vez de 0,02 segundos, o "mais lento por um fator de 7" não significa muito de qualquer coisa ... supondo que este não seja um servidor, é claro). Sei que muitas pessoas provavelmente alertarão sobre o potencial "perigo" de fazer edições tão profundas no sistema, mas eu diria que, se você estiver procurando por uma resposta como essa, provavelmente já sabe o suficiente para lidar com qualquer nomeação de utilitário conflitos que potencialmente possam surgir no futuro,/private/etc/pathsrealmente os propaga a todos os usuários / logins / instâncias possíveis - todos os programas, shells, etc. usarão os caminhos nesse arquivo para construir a base de sua $PATHvariável.

Para ser sincero, estou surpreso que mais ninguém aqui tenha mencionado isso ainda. Toda essa bagunça com o launchd e as distrações sobre usos específicos do SSH ... esta é a solução que qualquer pessoa que esteja procurando por esse problema básico está realmente procurando - a solução limpa, direta e sempre em funcionamento.

A propósito, no caso de você estar se perguntando, o OS X /etcé simplesmente um link simbólico para /private/etcque você possa fazer sudo nano /etc/pathso mesmo com facilidade e chegar ao mesmo local exato. O caminho acima é apenas o caminho real completo do arquivo.


2
A menos que esteja faltando alguma coisa, isso definirá apenas uma variável de ambiente para todo o sistema - $PATH. O OP parece estar à procura de uma solução genérica - definindo qualquer var env, todo o sistema, por exemplo $EDITOR, etc.
John N

Mesmo com o sudocomando, no macOS Sierra, recebo permissão negada se tentar criar, usando echoum novo arquivo que /private/etc/paths.dcontém uma adição ao caminho. Mas ele trabalha primeiro para criar o arquivo e depois sudo mvpara movê-lo /private/etc/paths.d.
murray 25/09

Isso ajudou. Outros diretórios estavam sendo anexados ao meu PATH, apesar de definir $ PATH no meu ~/.zshrc... o culpado era mesmo /private/etc/pathse eu tive que atualizar esse arquivo. Obrigado.
não ser

1

Eu tive um problema semelhante, especificamente ~/.bashrcnão estava sendo originado quando me conectei à minha máquina via SSH. Eu descobri que alterar uma configuração do SSHd fez o truque. Talvez o seu problema também esteja no daemon SSH?

Modifique o arquivo de configuração do serviço SSH da seguinte maneira:

# /etc/sshd_config
PermitUserEnvironment yes

Em seguida, reinicie o serviço Login Remoto em Preferências do Sistema> Compartilhamento.

Na página de sshd_configmanual:

 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.

(Caso isso ajude, escrevi como testei isso no meu wiki pessoal )


1

Se outros procurarem como definir variáveis ​​de ambiente para processos iniciados a partir de uma sessão de login gráfica normal, você poderá usar /etc/launchd.conf. Para, por exemplo, adicionar /usr/local/binao caminho padrão, execute

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

e reinicie para aplicar as alterações. Outra maneira de aplicar as alterações é executar launchctl</etc/launchd.conf;sudo launchctl</etc/launchd.confe reiniciar os processos.


O /etc/launchd.conf não é mais usado no launchd.
Uchuugaka

2
/etc/launchd.confnão é mais suportado desde OSX 10.10 Yosemite
wisbucky

0

Hmm ... A partir do Mac OS X 10.10.5 e provavelmente anterior, man -s5 launchd.confdiz-nos: " launchd.conf is no longer respected by the system." Eu tenho muita coisa acontecendo agora para colocar uma variável fictícia no arquivo e reiniciar para ver se realmente funciona ou não depois. tudo, mas a documentação diz que não deve funcionar.

Tenho certeza de que não. Faça man launchctle você verá: " The /etc/launchd.conf file is no longer consulted for subcommands to run during early boot time; this functionality was removed for security considerations."

O que você pode fazer é colocar todas as variáveis ​​de ambiente que você quer ser global em algum arquivo, talvez chamado environmentde acordo com o Linux, ou (caso a Apple decida fazer algo com isso mais tarde - você nunca sabe) environment.conf, como eu fiz, depois forneça isso via /etc/profile:

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

ou, se você preferir o formato compacto:

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

Se você usar outro shell que não seja o bash, e ele usar a mesma sintaxe de configuração variável do bash (como o zsh, acho), você também precisará obter esse arquivo do arquivo rc do sistema (por exemplo /etc/zshrc). Se você usar um shell que usa uma sintaxe diferente, por exemplo, tcsh, precisará manter um arquivo semelhante para esse shell e obtê-lo no arquivo rc do sistema (por exemplo, /etc/csh.cshrcpara tcsh) ou, melhor ainda, criar um script que o gera automaticamente, portanto, você só precisa editar um arquivo para adicionar / alterar variáveis. Este não é o lugar para esse tutorial; alguns segundos no Google, apareceu como converter exportações de variáveis ​​[t] csh para sintaxe bash, em https://stackoverflow.com/questions/2710790/how-to-source-a-csh-script-in-bash-to -configurar-o-ambiente, provavelmente há algo disponível para ir na outra direção.

Foi minha experiência que o Mac OS X está se afastando cada vez mais do comportamento previsível dos arquivos rc. A partir de pelo menos 10.8, ele parece não carregar mais /etc/rc.common, /etc/rc.confou /etc/rc.<anything>(desde pelo menos 10.9) será carregado /etc/bash.bashrcpara shells interativos sem logon (o que certamente deveria estar fazendo, assim como carrega ~/.bashrcpara eles, ainda, a partir de 10.10) . Então, novamente, eu tenho o Fink, MacPorts e Homebrew todos instalando coisas, então talvez um deles esteja interferindo no comportamento padrão do arquivo de pontos. YMMV.


A pergunta é para o OS X anterior, haverá outros, por exemplo, apple.stackexchange.com/questions/215932/… para mais tarde
user151019

Meu post abordou os Mavericks (10.9) em parte e as 10.10 em parte. Se o seu argumento é que 10.10 é um tópico detalhado inteiramente em um tópico sobre 10.9, não sei por que você me direcionou para um tópico 10.11, em que 10.10 também seria fora de tópico (se o tópico em questão não fosse inválido e fechado de qualquer maneira). RI MUITO.
S. McCandlish
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.