No OSX Yosemite, por que posso definir muitas variáveis ​​de ambiente para aplicativos da GUI, mas não posso definir a variável específica PATH

16

Depois que eu resolvi os problemas do OSX PATH até o lançamento do Mavericks, os problemas voltaram em Yosemite !!!

Então, eu quero imitar o launch.confrecurso antigo da nova versão do Mac OSX 10.10 Yosemite, para ter a variável de ambiente PATH em aplicativos de GUI como o Carbon Emacs ou o RStudio disponível. Eu usei a ótima idéia do usuário do stackoverflow ursa para configurar um shell script que configura variáveis ​​de ambiente via launchctl. (Veja a resposta do stackoverflow aqui .) Isso funciona para a maioria das variáveis ​​de ambiente, mas não para a variável PATH .

1. O que eu fiz?

Primeiro eu escrevi o /etc/environment.rcscript parecido com:

launchctl setenv PATH /Users/halloleo/bin:/usr/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv JAVA_HOME /usr/local/jdk1.7
launchctl setenv ENVIRONMENT_RC "yes"

Em seguida, criei as listas para launchd(listas desses e de outros scripts mencionados no apêndice abaixo). Então eu os ativei com

$ sudo launchctrl load ...

Então eu desabilitei o path_helper utilitário no /etc/perfil do arquivo shell init , para que ele não sobrescreva as environment.rcconfigurações. E, finalmente, reiniciei a máquina.

2. Qual é o efeito?

Quando inicio o Terminal, as novas variáveis ​​de ambiente JAVA_HOMEeENVIRONMENT_RC são definidas em função environment.rc, mas PATH está definido para

/ usr / bin: / bin

Para ter certeza, nenhum basharquivo init ficou no caminho. Em vez disso, escrevi um pequeno script python (no apêndice) para mostrar as variáveis ​​no ambiente atual e o executo diretamente clicando duas vezes em um ornitorrinco. wrapper . Novamente, as novas variáveis ​​são definidas, enquanto PATH possui o padrão do sistema.

Então, por que posso definir outras variáveis, mas não a variável PATH? E como posso resolver isso de maneira unificada ?

Atualizar:

A situação é muito intrigante: o shell ( bashpelo menos) no Terminal ou no Emacs selecionará o PATH que você definir por meio de launchctloutros aplicativos GUI, por exemplo, o script python mínimo mencionado diretamente chamado via Platypus não mostrará seu costume caminho. E até o próprio Emacs não conhece o CAMINHO correto: Você percebe isso, por exemplo, ao emitir o comando Emacs M-x ispell-buffer; a ferramenta unix ispellque o emacs tenta chamar não será encontrada se estiver apenas no seu caminho personalizado.


Apêndice

net.halloleo.environment.plist, o arquivo de configuração launchd em /Library/LaunchDaemons/:

<?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>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

net.halloleo.environment-user.plist, o arquivo de configuração launchd em /Library/LaunchAgents/:

<?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>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment-user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

/etc/profile, o arquivo de inicialização do bash modificado:

# System-wide .profile for sh(1)

# if [ -x /usr/libexec/path_helper ]; then
#   eval `/usr/libexec/path_helper -s`
# fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

show_environ.py, o script que exibe todas as variáveis ​​de ambiente:

import os
print (os.environ)
halloleo
fonte

Respostas:

3

PATH no Yosemite pode e deve ser definido no arquivo / etc / caminhos. Basta adicionar seu caminho ao final deste arquivo:

/usr/bin
/bin
/your/custom/path

O script / etc / environment na postagem original fornece suporte para a variável PATH em aplicativos da GUI (testada com o Emacs).

ursa
fonte
5
Isso funciona apenas para shells chamados /usr/libexec/path_helperdurante o processo de inicialização. Os aplicativos GUI não recebem o PATH de acordo com /etc/paths- e perguntei especificamente sobre aplicativos GUI.
Halloleo 28/10/14
Atualizei a resposta e o script / etc / environment na postagem original
ursa 28/10
Estas são duas respostas que você está dando - também o OP diz que / etc / environment não funciona #
user151019
@mark (1) depois que essa pergunta foi levantada, atualizei o / etc / environment e agora ele suporta PATH. (2) a resposta aqui é usar / etc / caminhos
ursa 28/10
2
@mark Sim, e esse é exatamente o meu ponto, problema e pergunta: como posso definir o PATH da variável de ambiente dos aplicativos da GUI quando lançados pelo Finder? Ainda assim, não real geral solução para isso à vista ...
halloleo
2

Isso me intrigou por um longo tempo (bem, nas últimas duas horas). No final, encontrei este relatório de erro, que parece descrever exatamente o meu problema (não sei até que ponto isso está relacionado ao seu problema, mas parece haver um bug no Yosemite / launchd em combinação com PATH e scripts como como python:

http://www.openradar.me/18945659

A solução parece ser iniciar um script de shell que inicia o python. Não é exatamente o que eu gosto, mas é assim ...

Claude
fonte
Obrigado pelo link para o relatório de erros. Bom agora é um bug real. Encontrei outra embreagem ao redor; Vou postar aqui.
halloleo
1

O problema é que o launchd anexa outra variável PATH em vez de substituir a variável no ambiente. A maioria dos programas usagetenv que sempre retorna a primeira ocorrência de uma variável, os shells iteram por todas as variáveis ​​de ambiente e importam-nas como variáveis ​​locais, substituindo, assim, as instâncias anteriores pela última.

Obviamente, isso é um bug no launchd; as variáveis ​​de ambiente passadas para um programa devem ser únicas.

StenSoft
fonte
11
Resposta de fundo legal! Eu acho que o theer não é o caminho real em conchas, ou existe?
Halloleo
@halloleo Você pode iniciar o comando como o sh -c 'YOUR ORIGINAL COMMAND'passa pelo shell, escolhendo o PATHconjunto no launchd.
StenSoft