Por que o / etc / profile não é invocado para shells que não são de login?

39

Shell de login e não-login definido como:

su - $USER # will give you a login shell
bash # will give you a non-login shell

/ etc / profile não é invocado para shells não-login, como quando você inicia o konsole (kde). / etc / profile é invocado apenas para shells de login.

Por que isso? Por favor explique, porque eu gosto de entender a lógica disso.

    
por James Mitch 26.01.2013 / 05:06

1 resposta

82

/etc/profile é invocado apenas para shells de login porque essa é sua finalidade específica.

Se você quiser que um comando seja executado para shells interativos que não sejam not , e estiver usando bash , coloque-o em ~/.bashrc ou /etc/bash.bashrc .

O propósito dos arquivos "profile" é conter comandos que devem ser executados apenas para shells de login. Esses arquivos são:

  • /etc/profile , executado por todos os shells compatíveis com Bourne (incluindo bash e dash ) quando iniciado como um shell de login.

  • Scripts em /etc/profile.d .

    Isto é para shells no estilo Bourne, mas não está codificado no próprio executável do shell. Em vez disso, os comandos em /etc/profile os chamam. Por exemplo, no meu sistema Ubuntu 12.04, /etc/profile inclui estas linhas:

    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i
        fi
      done
      unset i
    fi
    
  • .profile no diretório pessoal do usuário, executado por shells compatíveis com o Bourne quando iniciado como um shell de login (a menos que seja substituído, veja abaixo).

  • .bash_profile ou .bash_login no diretório pessoal do usuário. Estes são ignorados por shells diferentes de bash . Mas se existir .bash_profile , bash executará em vez de .profile . Se .bash_profile não existir, mas .bash_login existir, isso será executado em vez de .profile .

    (Mas é comum que .bash_profile ou .bash_login , quando existir, seja escrito para * explicitamente chamar .profile .)

    O benefício dos arquivos profile específicos do shell é que eles podem conter comandos ou sintaxe que são válidos apenas para esse shell. Por exemplo, posso usar o operador de avaliação [[ em .bash_profile / .bash_login , mas se eu usá-lo em .profile e, em seguida, efetuar login com dash como meu shell, ele falhará.

O que deve entrar em arquivos "perfil"

Arquivos "profile" devem conter comandos que devem ser executados apenas uma vez, no início do login. (Isso inclui logins gráficos, já que eles começam com um shell de login também.) Se um shell é interativo, o usuário que o está executando provavelmente está conectado, e provavelmente tem um ancestral (que o iniciou ou iniciou o que o iniciou, ou iniciei isso, etc.) que era um shell de login.

Você pode querer executar um comando apenas uma vez porque:

  1. não há razão para executá-lo mais de uma vez por login, seria ineficiente, ou
  2. produziria um resultado indesejado, para executá-lo mais de uma vez por login.

Como exemplo da segunda situação, em que um resultado indesejável ocorreria, considere estas linhas, que aparecem por padrão em todos os usuários ~/.profile :

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Suponha que você SSH em, correu outro shell (digamos, zsh ), em algum momento descobriu que você queria voltar temporariamente para bash , mas manter seu ambiente (então executou bash novamente em zsh ) e, em seguida, executou um programa como mc que executa um shell como parte de sua interface. Se bin existir em sua pasta pessoal e seu nome de usuário for james , sua PATH na parte interna é algo como:

/home/james/bin:/home/james/bin:/home/james/bin:/home/james/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Isso é ineficiente e (muito mais importante) dificulta a compreensão do conteúdo de PATH .

Isso não é um desastre, no entanto. Tanto quanto eu posso dizer, se cada shell interativo originasse arquivos "profile", nada terrível aconteceria, na configuração padrão . No entanto, como o propósito dos arquivos "profile" é conter comandos para executar apenas uma vez por login , um usuário ou administrador pode adicionar comandos a um perfil que deve ser executado apenas quando iniciando um shell de login.

Onde colocar comandos para cada shell interativo ser executado

Se você estiver usando bash , existem arquivos para comandos que devem ser executados em todos os shell interativos:

  • /etc/bash.bashrc
  • .bashrc no diretório pessoal do usuário.

Isso é mais comumente usado para comandos que

  1. afetam apenas o ambiente do shell em que são executados - nem mesmo shells filho, ou
  2. deve ser executado mesmo quando este não for o shell de login.

Por exemplo, a conclusão da tabulação da linha de comando deve estar habilitada ou não bash foi o shell de login. Então, isso aparece em ~/.bashrc :

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

Lá, 1 e 2 ambos se aplicam: isso não é transferido para outras camadas executadas dentro desta, e a conclusão da tabulação deve funcionar em bash mesmo se Eu entrei com um shell diferente.

Onde colocar comandos para shells de login e shells interativos não-login

Se você estiver usando bash e quiser que um comando seja executado em shells de login e shells interativos e que não sejam shells de login, geralmente é suficiente colocá-lo em /etc/bash.bashrc ou ~/.bashrc .Isso ocorre porque, por padrão, /etc/profile e ~/.profile os executam explicitamente. Por exemplo, ~/.profile tem:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

(Da mesma forma, /etc/profile sources /etc/bash.bashrc para bash .)

Assim, os arquivos "profile" e "rc" são executados quando você inicia um shell bash interativo (seja ou não um shell de login).

Onde colocar comandos para executar em shells não interativos

Você provavelmente não deseja especificar nenhum comando para todos os shells não interativos serem executados; eles seriam executados toda vez que um script fosse executado (desde que o script seja executado pelo shell que você configurou para executá-los).

Isso pode causar uma quebra substancial. Se você for fazer isso, e não houver uma conta de administrador no sistema além da que você está usando, talvez você queira criar uma; que pode facilitar a correção de erros.

Em bash , os arquivos "rc" são realmente executados se o shell é interativo ou não . No entanto, no topo eles dizem:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Então, se você precisa de comandos para executar automaticamente mesmo em shells não interativos como os que executam para executar scripts, você pode adicionar seus comandos antes dessas linhas.

Iniciando um Shell de Login

Efetuar login inicia um shell de login. Se você quer que um shell inicie depois disso, para se comportar como um shell de login, inicie-o com o -l flag (significa l ogin ). Por exemplo:

Essa é a melhor maneira de iniciar um shell de login (sem efetuar login), a menos que você queira iniciar um como outro usuário. Então, use:

  • sudo -i para root (use sudo -s para um shell raiz interativo de não login)
  • sudo -u username -i para qualquer usuário
  • su - username para usuários que não são root (use su username para um shell raiz interativo de não login)

O que é um shell de login inicial ?

Um shell de login inicial é o mesmo que um shell de login . Em toda parte esta resposta diz "shell de login" que poderia dizer "shell de login inicial" (exceto nesta seção, que já teria parado de fazer sentido).

Uma razão para o termo shell de login inicial é que login shell também é usado em um sentido diferente - para identificar qual programa é usado como o shell que é executado pelo logon. Este é o sentido do login shell usado para dizer:

Leitura Adicional

por Eliah Kagan 26.01.2013 / 08:27