Por que meu LD_LIBRARY_PATH tem terminal de inicialização não definido?

8

Eu tenho um shell script para configurar algumas variáveis de ambiente e lançar qualquer programa que eu enviar como argumento:

export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH
export TESTER="MY TEST VAR"

$@

Quando eu uso isso para chamar bash , por exemplo, funciona:

kjfletch@flatbed:~$ envrun.sh bash
kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH
/home/kjfletch/local/lib:
kjfletch@flatbed:~$ echo $TESTER
MY TEST VAR

Quando eu o uso para chamar um terminal ( xterm , aterm , ...) meu LD_LIBRARY_PATH fica indefinido:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Por que isso acontece? Como posso parar isso? (Eu estou executando o Debian 5.0)

Atualizar

Meu terminal não está chamando bash como um login:

kjfletch@flatbed:~$ echo $0
bash

Meu LD_LIBRARY_PATH não aparece em nenhum dos arquivos de inicialização do bash (além de .bash_history e ~ / .profile não existe.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
    
por kjfletch 21.08.2009 / 21:07

6 respostas

9

O binário do terminal provavelmente é setgid para o grupo utmp . Os binários setuid e setgid desabilitam LD_LIBRARY_PATH por motivos de segurança; veja ld.so(8) :

The necessary shared libraries needed by the program are searched for in the following order

  • Using the environment variable LD_LIBRARY_PATH (LD_AOUT_LIBRARY_PATH for a.out programs). Except if the executable is a setuid/setgid binary, in which case it is ignored.
    
por 01.10.2009 / 22:49
4

No terminal (xterm, aterm etc), verifique como o shell foi invocado: Um shell de login mostrará "-bash" e um shell que não seja de login mostrará "bash" quando você chamar echo $0 .

$ echo $0
-bash
$ bash
$ echo $0
bash

Um shell bash de login lerá o seguinte na ordem:

  1. / etc / profile
  2. ~ / .bash_profile
  3. ~ / .bash_login
  4. ~ / .profile

Verifique se algum desses arquivos existe e se eles reconfiguram a variável. Você também terá que seguir todos os arquivos que esses arquivos incluírem.

Se o bash não for invocado como um shell de login, ele ainda lerá os arquivos abaixo se for determinado como um shell interativo.

  1. /etc/bash.bashrc
  2. ~ / .bashrc

Uma maneira simples de determinar o tipo de bash shell que está sendo invocado é definir seu .bash_profile e .bashrc, e echo "Login shell" e "Interactive shell", respectivamente.

Depois que você souber o tipo de shell que está sendo chamado, terá a opção de adicionar seu script ao arquivo .bashrc ou .bash_profile em seu diretório pessoal. Como alternativa, você pode desativar a redefinição de LD_LIBRARY_PATH.

Observe que, se seu .bashrc ou .bash_profile estiver protegido por um protetor semelhante ao abaixo, talvez seja necessário chamar seu script para fora dele:

if [ "X$BASH_SOURCED" != "XYES" ]; then
        export BASH_SOURCED=YES

fi

Tais guardas são normalmente colocados para evitar que um script seja originado várias vezes em uma sessão.

Editar: Se estiver provando que é tedius rastrear onde a variável está sendo redefinida, e você tem acesso a / etc / profile ou /etc/bash.bashrc por exemplo, você pode adicionar temporariamente "set -x" no topo do script para ver todos os comandos executados. A saída será bem detalhada, então primeiro faça um "set -x" no seu shell e execute alguns comandos para que você saiba o que esperar.

    
por 22.08.2009 / 14:54
4
O

bash usará diferentes scripts de inicialização, dependendo de como ele é iniciado. Existem sete maneiras diferentes de iniciá-lo, mas as mais importantes são shells de login versus shells interativos que não são de login.

Confira o manual do bash para obter mais detalhes. Eu suspeitaria que o / etc / profile ou o ~ / .bash_profile está fazendo algo para redefinir a variável LD_LIBRARY_PATH.

Edit: Acho que você fez tudo o que pode para mostrar que o bash não possui nenhum script de inicialização que não seja configurado no LD_LIBRARY_PATH. É hora de trazer as grandes armas.

O comando a seguir exibirá todo o ambiente à medida que cada processo é iniciado, do bash ao xterm, e qualquer outra coisa que esteja envolvida - você provavelmente obterá uma grande quantidade de saída, portanto, salvar a saída em um arquivo é uma boa ideia.

strace -v -f -e trace=process -o strace_output.txt envrun.sh xterm

Agora, o arquivo strace_output.txt mostrará cada chamada de sistema feita pelo seu script e por cada processo filho, e você poderá ver qual processo foi o último a ter LD_LIBRARY_PATH antes de ser removido .

    
por 22.08.2009 / 00:02
2

(Esta questão é muito antiga, mas acabei de encontrar o mesmo problema e estou documentando a solução para posterioridade):

Eu tive esse problema com a tela GNU (o multiplexador de terminal), mas também pode acontecer com um terminal comum. Teddy estava certo no meu caso, tela tem setguid set.

$ ls -l /usr/bin/screen
-rwxr-sr-x 1 root 84 361016 Mar 30  2011 /usr/bin/screen
      ^

Minha solução foi salvar LD_LIBRARY_PATH antes da execução e restaurá-lo depois. Então criei um wrapper ~ / bin / screen (coloque ~ / bin no PATH), com o seguinte conteúdo:

#!/bin/bash

# somehow, screen resets LD_LIBRARY_PATH.
# save it here, and restore it in .bashrc
export PRESERVE_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
/usr/bin/screen "$@"

e, em seguida, tornou-o executável com chmod +x ~/bin/screen . Talvez seja necessário abrir um novo shell para que ele pegue o wrapper.

Depois adicionei o seguinte a ~ / .bashrc. Lembre-se que o ~ / .bashrc é originado toda vez que você inicia o bash, ao contrário do ~ / .bash_profile, que só é obtido no login (geralmente na inicialização, ou quando você faz o login no ssh).

if [[ "$PRESERVE_LD_LIBRARY_PATH" != "" ]]; then
    export LD_LIBRARY_PATH="$PRESERVE_LD_LIBRARY_PATH"
    #echo "restored LD_LIBRARY_PATH"
    export -n PRESERVE_LD_LIBRARY_PATH
fi

Agora a tela (ou aterm, xterm, ... apenas substitua-a acima) deve preservar $ LD_LIBRARY_PATH conforme desejado.

    
por 16.07.2012 / 11:10
0

Parece que você tem algum arquivo .bashrc (ou equivalente) em seu diretório inicial que define essa variável. Eu não sei muito mais detalhes.

Editar Ok, desde que comecei a trabalhar, acho que não o .bashrc. Mas talvez algum outro arquivo de configuração que seja executado da mesma maneira, quando você inicia o xterm ou aterm.

    
por 21.08.2009 / 21:09
0

A maioria dos sistemas de janelas recria o processo de login quando iniciam uma janela de terminal, principalmente porque a janela do terminal se torna o filho do gerenciador de janelas, não o shell de inicialização.

Então, coloque-o em seu .bash_profile ou .bashrc se quiser que ele apareça em uma nova janela.

Outra alternativa é entregar o xterm (por exemplo) um argumento para executar um script de inicialização. Não saia no final desse script ...

    
por 22.08.2009 / 00:06