Por que a fonte padrão ~ / .profile do Ubuntu ~ / .bashrc?

30

Este é o conteúdo do estoque ~/.profileque acompanha o meu 13.10 (linhas comentadas removidas):

if [ -n "$BASH_VERSION" ]; then
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Isso é herdado do Debian, mas por que a Canonical decidiu mantê-lo? Até onde eu sei, não é o caminho padrão * nix e vi vários sistemas em que isso não aconteceu, então presumo que eles devam ter um bom motivo. Isso pode causar um comportamento inesperado ao executar shells de logon (como, por exemplo, quando sshing na máquina, por exemplo), em que o usuário não esperaria ter ~/.bashrcorigem.

O único benefício que consigo pensar é em não confundir o usuário com muitos arquivos de inicialização e permitir que ele edite .bashrcsozinho e faça a leitura independentemente do tipo de shell. Isso, no entanto, é um benefício duvidoso, pois geralmente é útil ter configurações diferentes para login e shells interativos, o que impede você de fazê-lo. Além disso, os shells de login geralmente não são executados em um ambiente gráfico e isso pode causar erros, avisos e problemas (oh meu!), Dependendo do que você definiu nesses arquivos.

Então, por que o Ubuntu faz isso, o que estou perdendo?

terdon
fonte
Por que -n "$BASH_VERSION"seria verdade fora do bash?
Elliott Frisch
@ ElliottFrisch não será. Minha pergunta é por que o .profilesource .bashrc, esse não é o caso em todas as versões do Linux, e estou me perguntando qual é a lógica por trás disso.
terdon
Parece ser implementado dessa maneira no debian upstream.
Elliott Frisch
@ ElliottFrisch sim, eu pensei que não era e procurei e vi que estava na hora de editar meu comentário. No entanto, não é o caso de um sistema SuSe ao qual tenho acesso (embora seja do CentOS) e não era o caso de vários sistemas (RHs, Fedoras, Ubuntus mais antigo) até onde me lembro. Então, eu estou me perguntando o porquê.
terdon

Respostas:

15

Esta é uma decisão upstream vinda do Debian. A justificativa para isso é explicada neste post wiki muito agradável , do qual o seguinte é um trecho. O resumo executivo é "para garantir que os logins da GUI e não da GUI funcionem da mesma maneira":

Vamos considerar o xdm como um exemplo. pierre volta das férias um dia e descobre que o administrador do sistema instalou o xdm no sistema Debian. Ele efetua login muito bem e o xdm lê seu arquivo .xsession e executa o fluxbox. Tudo parece estar bem até que ele receba uma mensagem de erro no local errado! Como ele substitui a variável LANG em seu .bash_profile e como o xdm nunca lê .bash_profile, sua variável LANG agora está definida como en_US em vez de fr_CA.

Agora, a solução ingênua para esse problema é que, em vez de iniciar o "xterm", ele poderia configurar seu gerenciador de janelas para iniciar o "xterm -ls". Este sinalizador informa ao xterm que, em vez de iniciar um shell normal, ele deve iniciar um shell de login. Sob essa configuração, o xterm gera / bin / bash, mas coloca "- / bin / bash" (ou talvez "-bash") no vetor de argumento; portanto, o bash age como um shell de login. Isso significa que toda vez que ele abrir um novo xterm, ele lerá / etc / profile e .bash_profile (comportamento bash embutido) e, em seguida, .bashrc (porque .bash_profile diz para fazer isso). Isso pode parecer funcionar bem no começo - seus arquivos de ponto não são pesados, então ele nem percebe o atraso - mas há um problema mais sutil. Ele também lança um navegador da web diretamente do menu do fluxbox, e o navegador da Web herda a variável LANG do fluxbox, que agora está definido como o código de idioma errado. Portanto, enquanto seus xterms podem estar bem, e qualquer coisa lançada a partir dele pode estar bem, seu navegador ainda está fornecendo páginas no local errado.

Então, qual é a melhor solução para esse problema? Realmente não existe um universal. Uma abordagem melhor é modificar o arquivo .xsession para algo parecido com isto:

[ -r /etc/profile ] && source /etc/profile
[ -r ~/.bash_profile ] && source ~/.bash_profile
xmodmap -e 'keysym Super_R = Multi_key'
xterm &
exec fluxbox

Isso faz com que o shell que está interpretando o script .xsession leia em / etc / profile e .bash_profile, se eles existirem e forem legíveis, antes de executar o xmodmap ou o xterm ou "executar" o gerenciador de janelas. No entanto, há uma desvantagem potencial nessa abordagem: no xdm, o shell que lê .xsession é executado sem um terminal de controle. Se / etc / profile ou .bash_profile usarem comandos que pressupõem a presença de um terminal (como "fortuna" ou "stty"), esses comandos poderão falhar. Essa é a principal razão pela qual o xdm não lê esses arquivos por padrão. Se você usar essa abordagem, verifique se todos os comandos em seus "arquivos de ponto" são seguros para executar quando não houver terminal.

terdon
fonte
Ainda acho que não é uma ótima ideia. O ideal seria garantir que o gerenciador de exibição crie um perfil global (verificação) e o perfil do usuário .profile. Agora eu sei por que eu tenho caminhos duplicados em algumas variáveis ​​...
Rmano 18/03
2

Esse é o comportamento padrão do Ubuntu, ~/.bashrcé o arquivo de inicialização por shell interativo no nível do usuário. Quando você abre um terminal, basicamente inicia um shell interativo sem login, que lê ~/.bashrce o conteúdo ~/.bashrcé obtido e exportado para o ambiente atual do shell. Isso ajuda a obter todas as variáveis e funções de shell definidas pelo usuário no shell atual. Além disso, você pode encontrar linhas como esta

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

para obter aliases definidos pelo usuário no ambiente de shell atual.

Isso é importante para fornecer também uma boa experiência do usuário. Por exemplo, pode armazenar na credencial de proxy .bashrc, a menos que se nenhum dos aplicativos de terminal de origem ( ou seja , ping, wget, curl, lynxetc.) irá funcionar corretamente. Ou você precisa fornecer as credenciais de proxy sempre que abrir um terminal.

Além do padrão do Ubuntu .bashrcconter muitos apelidos amigáveis ​​ao usuário (para lse grepimprimir saída colorida), muitas novas definições para diferentes variáveis ​​de shell, o que aumenta a experiência do usuário.

Mas, no caso de seu login ssh ou login no console virtual , você basicamente obtém um shell de login interativo. Aí está o arquivo de iniciação do shell ~/.profile. Portanto, a menos que ~/.bashrcvocê obtenha a fonte, perde todas essas configurações úteis no seu .bashrc. É por isso que a ~/.profilefonte padrão do Ubuntu~/.bashrc

Caso a evitar

  • você nunca deve obter o ~/.profileformulário dentro dele ~/.bashrcao mesmo tempo em que ~/.bashrcestá sendo originado ~/.profile. Isso criará um loop infinito de situação e, como resultado, o prompt do terminal será suspenso, a menos que você pressione Ctrl+ C. Em tal situação, se você colocar uma linha no seu~/.bashrc
set -x

Então você pode ver que o descritor de arquivo está parando quando você abre um terminal.

souravc
fonte
Obrigado, todas essas informações são verdadeiras e úteis. Apenas não aborda minha pergunta. Eu estou familiarizado com as diferenças entre shells de login e não-login. Minha pergunta é por que, nos sistemas Ubuntu, é o .profilesourcing .bashrc? O SuSe Enterprise 10 não faz isso, nem nenhuma das versões do Fedora que usei, mas há alguns anos atrás, posso estar errado. CentOS 5.8 faz estranhamente o suficiente. Enfim, você entende o meu ponto? Esta é uma escolha de design e estou me perguntando por que foi feita.
terdon
Eu não usei rigorosamente as outras distribuições Linux que você nomeou. você pode me dizer como eles lidam com situações como comandos com alias na sessão ssh que são definidos dentro .bashrcou dentro .bash_aliases. Por exemplo, eu tenho um pseudônimo para lscomo ls --color=autono meu .bashrce .bashrcobtive o meu .profile. Aqui eu posso usar o alias mesmo do ssh. Ou eu poderia usar proxy na sessão ssh. Se eu não fonte meu .bashrcde .profileeu perder esses recursos. Eu acho que é tudo sobre uma melhor experiência do usuário.
souravc 11/03/14
Eles não, esses aliases não funcionam. E sim, a fonte .bashrccorrige isso. Mas isso também causa problemas. Lembro-me da primeira vez em que usei um sistema com esse comportamento. Recebi essas mensagens estranhas ao sshusá-lo, porque estava usando xset b offno meu .bashrcque desabilitava a campainha do terminal, mas apenas em um sistema X, para que estava dando mensagens de erro. Levei anos para descobrir o que estava acontecendo, pois eu não achava que isso .bashrcseria lido ao executar um shell de login. Só estou me perguntando se há uma declaração "oficial" sobre isso.
terdon
Eu concordo com você. Eu também enfrentei alguns problemas mais cedo . Mas é principalmente útil e amigável, se você se lembrar e evitar alguns casos especiais. Não é :)
souravc
Sim, existem razões válidas para isso. Eu estava curioso para saber se a Canonical já havia dado sua justificativa para manter essa decisão a montante.
terdon