Bash shell: como reconciliar arquivos de configuração portáteis e tipos de inicialização do terminal GUI (login ou interativo)?

4

Em uma tentativa de "corretamente" implementar uma configuração padrão do meu shell preferido, bash , para uso em múltiplas plataformas, eu me deparei com alguma confusão ao lidar com terminais que são inconsistentes com sua escolha de inicialização de shell. tipos up (login ou interativo).

Arquivos de inicialização do bash

No manual bash, determinei a diferença entre os arquivos de inicialização e os pedidos / casos nos quais eles são originados ( /etc/profile , ~/.bash_profile , ~/.bash_login e ~/.profile para as cascas de login, e ~/.bashrc para shells não-login interativos). A documentação sugeriu que você armazenasse sua configuração de login bash-specfic em ~/.bash_profile e suas interativas específicas do bash no seu ~/.bashrc . O próprio manual até sugeriu a adição de if [ -f ~/.bashrc ]; then source ~/.bashrc; fi ao arquivo ~/.bash_profile , para que os shells de login herdam suas configurações interativas do shell.

Pelo que li no manual e em vários fóruns / documentos on-line, também pareceu prudente abstrair sua configuração de login não específica do bash para ~/.profile , já que outras shells podem originar esse arquivo. Isso pode ser uma vantagem para as pessoas que podem usar o Bourne shell, além do bash (o que não é muito provável no meu caso), mas parece um bom hábito se formar.

Até agora, tudo isso parece bastante direto e lógico, especialmente em um ambiente onde a distinção entre os vários tipos de inicialização de shell é aparente: em sistemas ou terminais onde a linha de comando é a interface principal, os shells de login são seus shells de sessão primária, shells interativos são shells subsequentes lançados naquela sessão e seus shells não interativos são shells executados por script.

A verdadeira confusão é o que constitui um shell de login quando seu shell é iniciado a partir de um terminal dentro de um ambiente GUI onde você já está autenticado no sistema? Parece-me que o comportamento padrão no Mac O OSX Terminal.app é para o shell em execução em cada janela para iniciar um shell de login, enquanto que no xterm, cada nova janela é um shell interativo.

É possível que eu esteja vendo um problema onde não existe um, no entanto considere o seguinte: a situação do terminal sugere que eu coloquei a grande maioria da minha configuração em ~/.bashrc para evitar a perda de funcionalidade se eu estivesse trabalhando em um terminal que inicia o bash como um shell interativo. Não estando familiarizado com as complexidades de quando o bash pode ser gerado como shells interativos, eu tenho que confiar em esta declaração de que abusar de ~/.bashrc desta forma acabará por causar problemas nos quais a configuração da shell de login sendo perdida é prejudicial ao funcionamento normal da shell. Não é difícil imaginar que possam surgir problemas quando você ignora o conselho do manual e usa os arquivos de configuração de forma inadequada.

Como você não pode confiar em usar ~/.bashrc como seu todo, parece que você deve tratar seus arquivos ~/.bash_profile e ~/.bashrc de maneira diferente, dependendo do terminal que estiver usando. Isso parece resultar em muitas dores de cabeça e é contrário ao propósito de ter esses arquivos distintos de inicialização em primeiro lugar!

Então, finalmente, minhas perguntas são as seguintes:

  • Como os atuais usuários do shell Bash abordam o problema das inconsistências do terminal da GUI entre o início do login e os shells interativos?
  • Como você cria um conjunto único de arquivos de inicialização bash para uso entre plataformas (e entre terminais), sem incorrer em problemas?

Obrigado pela sua ajuda e conselhos.

    
por jmlane 02.12.2010 / 06:58

1 resposta

4

O problema mais comum causado pelo uso incorreto de arquivos de inicialização do shell é que, se você definir variáveis de ambiente em .bashrc em oposição a .profile , elas não serão definidas em aplicativos que não são iniciados a partir de um shell em um terminal, mas de um menu GUI.

Definir variáveis de ambiente de .bashrc geralmente não é uma boa ideia, mas isso é principalmente porque geralmente é inútil, já que as variáveis já devem ter sido definidas no momento do login. Isso pode causar um problema na prática se você (ou um aplicativo) alterar deliberadamente o valor de uma variável (por exemplo, PATH ) em um programa e iniciar um shell a partir desse programa e esperar que a configuração permaneça a mesma. / p>

Você pode evitar o problema de redefinir as variáveis de ambiente definindo um valor de "sentinela" e não definir nada se o valor da sentinela estiver definido:

if [ -z "$JMLANE_PROFILE_READ" ]; then
  export ...
  export JMLANE_PROFILE_READ=1
fi

Outro problema causado por terminais que iniciam shells de login é que há coisas que só devem ser feitas uma vez quando você efetua login, por exemplo, iniciando um agente de senha (por exemplo, ssh-agent ) ou iniciando uma sessão (por exemplo, executando startx em certas circunstâncias). A variável sentinela evita esses problemas.

Um shell dentro de um terminal é sempre interativo. Contanto que você escolha .bashrc de .bash_profile quando o shell for interativo, você não precisa se preocupar com o terminal que inicia um shell de login.

Uma verruga adicional da manipulação de arquivos de inicialização do bash é que .bashrc é lido por shells não interativos invocados por rshd ou sshd. Por exemplo, quando você executar rsync somefile host.example.com: , se o seu shell de login em host.example.com for bash, você poderá usar .bashrc lá para definir o caminho para incluir rsync . Você pode dizer que está nesta situação porque .bashrc é lido de um shell não interativo.

## .bashrc
if [[ $- != *i* ]]; then
  # either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
fi
    
por 03.12.2010 / 02:42