O GNU Screen não herdará meu PATH na versão 10.5.8

11

Uso a tela diariamente para minhas necessidades de terminal e estou muito feliz com isso. Recentemente, porém, eu fiz algumas atualizações para os meus arquivos de configuração bash e notei que eu estava assentado vários PATHelementos ( PATH, MANPATH, INFOPATH, etc) em 2 lugares. Modifiquei os arquivos para serem o que deveriam ser e agora todas as minhas variáveis ​​de ambiente são definidas uma vez .bash_profile. Aqui reside o meu problema.

Aparentemente, o motivo de colocá-los em dois lugares foi por causa da tela. tela parece executar apenas .bashrce não não parece herdar PATHcorretamente minhas ou quaisquer outras variáveis ​​de ambiente do meu shell bash original. Como ele é executado apenas .bashrce agora defino apenas minhas variáveis .bash_profile, recebo um incompleto PATH.

Minha pergunta, então, é como colocar minhas variáveis ​​de ambiente na tela sem a duplicação. Lendo através doBash documentos parece indicar que poderia ser o tipo de shell que a tela usa para efetuar login, ou seja, um shell interativo sem login, mas não consegui descobrir como forçar a tela a usar um tipo específico de shell, apenas o shell para usar via -s /bin/bash.

Você pode ler meus arquivos de configuração em minha página do GitHub . Esse é o commit de confirmação que quebrou a tela .

EDITAR: eu estou usando Screen version 4.00.03 (FAU) 23-Oct-06e tendem a invocá-lo porscreen -h 50000

EDITAR: Agora eu tenho sido capaz de testar isso no Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06) e exibe um comportamento diferente do que no meu Mac.

O comportamento específico que descobri agora é que, no Cygwin, as alterações feitas PATHno arquivo .bash_profile são duplicadas ao entrar na tela e, em seguida, a criação sucessiva de janelas de tela não duplica o caminho, mas gera novamente o arquivo .bash_profile.

Para ilustrar o comportamento de que estou falando:

Saída de um terminal novo:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Saída da primeira chamada da tela:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Chamadas subsequentes para C-a c:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Você pode ver

Tim Visher
fonte
A duplicação ocorre porque você configurou o bash para adicionar incondicionalmente essas entradas, pois é um shell de 'login' e está dizendo à tela para invocar o bash como um shell de 'login'. Reescrevi minha resposta para tentar resolver os problemas gerais de shells, tela e variáveis ​​de ambiente.
quer

Respostas:

16

Variáveis ​​de tela e ambiente

Por padrão, a tela passa para seus shells (e outros processos), independentemente das variáveis ​​de ambiente que possuía quando a sessão foi iniciada (ou seja, a reconexão não altera quais variáveis ​​de ambiente são dadas aos novos shells). Mas como os arquivos de configuração da tela e dos shells geralmente alteram as variáveis ​​de ambiente, há muitos locais onde alterações inesperadas podem ser introduzidas. Existem algumas variáveis, como TERM , que a tela quase sempre muda, mas geralmente são necessárias para a funcionalidade que a tela fornece.

Digamos que nem a configuração do seu shell, nem a configuração da tela modificarão uma variável chamada FOOBAR (provavelmente, no total). Se você iniciar uma sessão FOOBAR=foo screen, todos os shells criados nessa sessão terão uma variável de ambiente chamada FOOBAR com um valor de foo.

As coisas ficam mais complicadas para variáveis ​​que a tela ou seu shell podem modificar.

Configurações ausentes ao usar a tela

Conchas de login

Se você achar que algumas configurações estão ausentes nos shells iniciados pela tela , pode ser porque o seu shell está configurado apenas para atualizar essas configurações para shells de 'login'. A maioria das conchas compreender uma convenção especial (em C: **argv == '-') que a tela pode ser configurada para uso.

De acordo com a documentação da tela :

comando shell

Defina o comando a ser usado para criar um novo shell. Isso substitui o valor da variável de ambiente $ SHELL. Isso é útil se você deseja executar um tty-enhancer que espera executar o programa especificado em $ SHELL. Se o comando começar com um caractere '-', o shell será iniciado como um shell de login.

Para ter shells de início de tela como shells de 'login', inicie a tela com screen -s -/bin/bashou adicione esta linha ao seu .screenrc:

shell -/bin/bash

Ajuste o caminho para o shell que estiver usando.

Configuração da tela

Falta ou variáveis de ambiente de reset também pode ser devido a setenve unsetenvcomandos em uma tela de arquivo de configuração. Você precisará verificar o .screenrc no diretório inicial e o arquivo que sua compilação de tela estiver usando como 'system screenrc' (você pode tentar um comando como strings "$(which screen)" | fgrep -i screenrcencontrar o nome do caminho que foi configurado no tempo de compilação - geralmente é / etc / screenrc para uma tela instalada pelo sistema ; as instalações complementares provavelmente usarão outro nome de caminho). Você pode usar SCREENRC=/dev/null SYSSCREENRC=/dev/null screenpara evitar temporariamente esses arquivos de configurações, mas existe uma opção em tempo de compilação que impede o uso efetivo do SYSSCREENRC (presumivelmente para que os administradores do sistema possam forçar um pouco da configuração inicial).

Configurações duplicadas ao usar a tela

É bastante comum adicionar itens a uma variável de ambiente como PATH no (s) arquivo (s) de configuração do shell, para que o valor atualizado esteja disponível para sessões normais do shell (por exemplo, xterm ou outras janelas de terminal, sessões de console etc.). Se esses itens forem adicionados na configuração por shell de um shell (ou, se você estiver usando a -/path/to/shellconfiguração descrita acima, na configuração de shells por login), o shell iniciado pela tela provavelmente terá várias cópias dos itens adicionados.

Uma estratégia para evitar isso é colocar todas as adições a variáveis ​​como PATH na configuração por login do seu shell e evitar o uso da -/path/to/shellconfiguração do shell com a tela .

Outra estratégia é adicionar apenas condicionalmente os novos itens à variável. Dependendo do shell, o código para fazer isso pode ser um pouco complicado, mas geralmente pode ser encapsulado em uma função shell para facilitar o uso.

Outra estratégia é sempre começar com um valor fixo nos seus arquivos de configuração. Às vezes, isso pode causar problemas ao mover seus arquivos de configuração de sistema para sistema, quando os valores padrão podem variar significativamente.

Diagnóstico

Se você não conseguir identificar diretamente onde uma modificação específica está ocorrendo, tente o seguinte para localizar onde a alteração está ocorrendo.

Verifique o valor atual no seu shell inicial:

echo "$PATH"

Verifique como o próprio shell modifica o valor quando um sub-shell é criado:

/bin/bash -c 'echo "$PATH"'

Verifique como o shell modifica o valor quando um sub-shell 'login' é criado:

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

Verifique como a tela modifica o valor:

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log
Chris Johnsen
fonte
Isso resolve parte do meu problema. Infelizmente, não segue o caminho completo. Agora, a tela está funcionando bem, screen -s -/bin/bashmas não se comporta como eu esperava que se comportasse sob Cygwin na minha máquina de trabalho. Naquela máquina, eu corro screen -h 50000e ela simplesmente herda a minha, PATHsem realmente obter o arquivo novamente. Isso é executado sempre que inicio uma nova janela.
Tim Visher
O ambiente do processo de tela sempre deve ser herdado por qualquer um de seus filhos (exceto para itens como TERM que podem ser substituídos). Experimente FOOBAR=baz screene verifique echo $FOOBARas janelas do shell de screene screen -s -/bin/bash. Ambas as variações devem ter FOOBAR= baz. Se você PATHestá sendo modificado, terá que rastrear o que está fazendo isso. Tente SYSSCREENRC=/dev/null SCREENRC=/dev/null screen, se isso permitir PATH, é provavelmente um setenv PATHin /etc/screenrcou ~/.screenrc. Caso contrário, é algo que você .bashrcestá fazendo.
Chris Johnsen
Fiz uma grande reescrita / adição à minha resposta.
quer
2

A última vez que vi um problema semelhante, resolvi usando screen -lao iniciar a tela.

Você pode usar a -lopção ao chamar screen(ativar o modo de login ; também controlado pelos comandos deflogine ) para definir se a tela deve efetuar login na janela por padrão (adicionando / removendo a entrada / etc / utmp).login.screenrc

O modo de logon está ativado por padrão, mas isso pode ser alterado no momento da compilação. Se a tela não for compilada com suporte a utmp, esses comandos não estarão disponíveis.

Parece que não preciso do -lmodo na tela padrão do Debian Lenny (v4.0.3); parece estar ativado por padrão. Meu ~/.profilee ~/.bashrcestá sendo lido corretamente. Como você está invocando screen? Qual versão você está usando?

charlatão quixote
fonte
Ainda segundo essa teoria, nãoscreen -ln devo executar o meu e ainda será executado. então tente a bandeira, mas essa provavelmente não é a resposta certa. vai deixar aqui por enquanto. ~/.profile-l
quack quixote
Parece que -lapenas controla se screenadiciona uma entrada ao utmparquivo, não se chama novas conchas com sua própria -lopção ou usa o -costume exec-with- prefefix.
Chris Johnsen
2

O problema está no comportamento de inicialização no Leopard. Veja este relatório de bug do MacPorts para a tela no Leopard para ver por que ele nunca será corrigido, a menos que você possa, de alguma forma, dar suporte ao lançamento do Snow Leopard.

https://trac.macports.org/ticket/18235#comment:26

ClashTheBunny
fonte
1

Não há nada errado em obter o seu .bashrc a partir de .bash_profile. Se você estiver usando sua máquina apenas localmente, seu perfil .bash_profile na maioria dos casos só será originado quando você fizer seu login inicial (obviamente há outras vezes em que ela é obtida).

Organizo meus arquivos para que, se eu quiser que algo seja feito apenas quando eu fizer o login, coloquei as informações em .bash_profile e, para todo o resto, as coloque em .bashrc. PATH é uma coisa que eu coloquei no meu .bashrc e forneço .bashrc no meu .bash_profile.


fonte
Você se sentiria confortável postando seus arquivos .bashrce em .bash_profilealgum lugar para que eu pudesse vê-los? O problema que encontrei ao fazer algo semelhante era que PATHaumentava toda vez que eu criava uma nova instância de tela porque herdava a antiga PATHe, em seguida, adicionava tudo novamente.
Tim Visher 28/02/10
Desculpe Tim, eu não vi isso ... Eu mudei muitas coisas para que elas não fizessem muito sentido, mas isso é basicamente o que eu faço. # .bash_profile if [-f ~ / .bashrc]; então . ~ / .bashrc fi Em seguida, coloco todo o resto em .bashrc, exceto as coisas que quero iniciar no primeiro login, que também entram em .bash_profile. PATH é tratado em .bashrc como uma série de linhas em vez de uma definição de caminho como a maioria faz export PATH = / path / to / binaries1: $ export PATH PATH = / path / to / binaries2: $ PATH
0

Sempre que tenho algum problema, como que eu criar um arquivo $HOME/.debuge em todos os arquivos de origem / executada durante o login invocação / shell (por exemplo ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrc, etc) Tenho como a primeira linha

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

ou similar. Para depuração específica, você também pode adicionar coisas como

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

Dessa forma, você pode ter 100% de certeza absoluta de quais arquivos são ou não usados.

O redirecionamento para o stderr é importante, você não deseja que algo atrapalhe o stdout em muitas situações.

hlovdal
fonte
0

Você pode permanecer com .profile, já que o sistema não toca no bashrc (como uma sessão de gráficos). Agora você tem apenas dois conjuntos diferentes de ambiente - um do .profile e outro para o bash do .bashrc.

ZaB
fonte