¿Por qué mi LD_LIBRARY_PATH obtiene un terminal de inicio sin configurar?

8

Tengo un script de shell para configurar algunas variables de entorno y ejecutar cualquier programa que envíe como argumento:

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

$@

Cuando uso esto para llamar, bashpor ejemplo, funciona:

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

Cuando lo uso para llamar a un terminal ( xterm, aterm, ...) mi LD_LIBRARY_PATHconsigue desarmar:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

¿Por qué pasó esto? ¿Cómo puedo detener esto? (Estoy ejecutando Debian 5.0)

Actualizar

Mi terminal no está llamando a bash como inicio de sesión:

kjfletch@flatbed:~$ echo $0
bash

Mi LD_LIBRARY_PATHno aparece en ninguno de los archivos de inicio de bash (aparte de .bash_history y ~ / .profile no existe):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
fuente
¿Alguno de esos archivos de inicio llama al comando "fuente" o al "." comando para traer otros scripts de inicio? Si es así, uno de esos puede ser el culpable.
Kevin Panko
No responde su pregunta, pero lo realmente bueno sería deshacerse de la necesidad de LD_LIBRARY_PATH (razones: 1 2 3 ). Podría, por ejemplo, editar /etc/ld.so.conf, o compilar las bibliotecas definidas por el usuario que tenga en ~ / local de manera que sepan dónde encontrar sus bibliotecas (vea los enlaces que proporcioné).
DevSolar

Respuestas:

9

El terminal binario es más probable setgidque se agrupe utmp. Los binarios setuid y setgid no están configurados LD_LIBRARY_PATHpor razones de seguridad; ver ld.so(8):

Las bibliotecas compartidas necesarias que necesita el programa se buscan en el siguiente orden

  • Uso de la variable de entorno LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHpara a.out programas). Excepto si el ejecutable es un binario setuid / setgid, en cuyo caso se ignora.
Osito de peluche
fuente
4

En el terminal (xterm, aterm, etc.), verifique cómo se invocó el shell: un shell de inicio de sesión mostrará "-bash" y un shell sin inicio de sesión mostrará "bash" cuando llame echo $0.

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

Un shell bash de inicio de sesión leerá lo siguiente en orden:

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

Compruebe si existe alguno de estos archivos y si restablecen la variable. También tendrá que seguir cualquier archivo que estos archivos incluyan.

Si bash no se invoca como un shell de inicio de sesión, seguirá leyendo los archivos a continuación si se determina que es un shell interactivo.

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

Una manera simple de determinar el tipo de shell bash que se invoca es definir su .bash_profile y .bashrc, y hacer eco de "Shell de inicio de sesión" y "Shell interactivo" respectivamente.

Una vez que sepa el tipo de shell que se invoca, tiene la opción de agregar su script al archivo .bashrc o .bash_profile en su directorio de inicio. Alternativamente, puede deshabilitar el restablecimiento de LD_LIBRARY_PATH.

Tenga en cuenta que si su .bashrc o .bash_profile está protegido por una protección similar a la siguiente, es posible que deba llamar a su script fuera de él:

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

fi

Tales guardias normalmente se colocan para evitar que un script se obtenga varias veces en una sesión.

Editar: si está demostrando que tedius puede rastrear dónde se restablece la variable, y tiene acceso a / etc / profile o /etc/bash.bashrc, por ejemplo, puede agregar temporalmente "set -x" cerca de la parte superior del script para ver todos los comandos que se ejecutan. El resultado será bastante detallado, así que primero haga un "set -x" en su shell y ejecute algunos comandos para que sepa qué esperar.


fuente
+1 Gracias por la información. He actualizado mi OP en respuesta a su respuesta.
kjfletch
¿Ves el mismo comportamiento si ingresas un nuevo shell bash en la misma terminal escribiendo bash? Por cierto, también deberá verificar los archivos que se invocan desde /etc/bash.bashrc y / etc / profile; uno de ellos podría desarmar la variable. Alternativamente, use la set -xopción de depuración para obtener un volcado de todo lo que se hace desde el momento en que se crea el shell.
El set -xvolcado no hace referencia a LD_LIBRARY_PATH. Fantasma desarmado.
kjfletch
4

bash usará diferentes scripts de inicio dependiendo de cómo se inicie. Hay siete formas diferentes de iniciarlo, pero las más importantes son las shells de inicio de sesión versus las shells interactivas sin inicio de sesión.

Consulte el manual de bash para más detalles. Sospecharía que / etc / profile o ~ / .bash_profile está haciendo algo para restablecer la variable LD_LIBRARY_PATH.


Editar: creo que ha hecho todo lo posible para mostrar que bash no tiene ningún script de inicio que desarme LD_LIBRARY_PATH. Es hora de sacar las armas grandes.

El siguiente comando mostrará todo el entorno a medida que se inicia cada proceso, desde bash hasta xterm, y cualquier otra cosa que esté involucrada; probablemente obtendrá una gran cantidad de salida, por lo que es una buena idea guardar la salida en un archivo .

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

Ahora, el archivo strace_output.txt mostrará cada llamada al sistema realizada por su script y cada proceso secundario, y podrá ver qué proceso fue el último en tener LD_LIBRARY_PATH antes de que se elimine.

Kevin Panko
fuente
2

(Esta pregunta es muy antigua, pero acabo de encontrar el mismo problema y estoy documentando la solución para la posterioridad :)

He tenido este problema con la pantalla GNU (el multiplexor de terminal), pero también puede ocurrir con un terminal normal. Teddy tenía razón en mi caso, la pantalla se ha establecido.

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

Mi solución fue guardar LD_LIBRARY_PATH antes de la ejecución y restaurarlo después. Así que creé un contenedor ~ / bin / screen (poner ~ / bin en PATH), con el siguiente contenido:

#!/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 "$@"

y luego lo hizo ejecutable con chmod +x ~/bin/screen. Puede que tenga que abrir un nuevo shell para que recoja el contenedor.

Luego agregué lo siguiente a ~ / .bashrc. Recuerde que ~ / .bashrc se obtiene cada vez que inicia bash, a diferencia de ~ / .bash_profile, que solo se obtiene al iniciar sesión (generalmente al inicio o cuando inicia sesión a través de 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

Ahora la pantalla (o aterm, xterm, ... solo sustitúyala arriba) debería conservar $ LD_LIBRARY_PATH como lo desee.

jdm
fuente
También puede restaurar LD_LIBRARY_PATHen .screenrc( en lugar de .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"seguido deunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Parece que tiene algún archivo .bashrc (o equivalente) en su directorio de inicio que define esta variable. Sin embargo, no sé muchos más detalles.

Editar Ok, ya que comenzar bash funciona, supongo que no es el .bashrc. Pero tal vez algún otro archivo de configuración que se ejecute de la misma manera, cuando inicie xterm o aterm.

Gnoupi
fuente
Este fue mi pensamiento original. Después de mucho buscar no hay nada que encontrar. Tengo el beneficio de tener un $ HOME muy limpio (NUEVO).
kjfletch
0

La mayoría de los sistemas de ventanas recrean el proceso de inicio de sesión cuando inician una ventana de terminal, principalmente porque la ventana de terminal se convierte en el elemento secundario del administrador de ventanas, no en el shell de inicio.

Por lo tanto, póngalo en su .bash_profile o .bashrc si desea que aparezca en una nueva ventana.

Otra alternativa es entregar a xterm (por ejemplo) un argumento para ejecutar un script de inicio. No salgas al final de ese script ...

kmarsh
fuente
Creo que tendré que recurrir a esto. Probablemente obtendré mis variables de entorno en .xinitrc para que mi administrador de ventanas las tenga, y en .bashrc para que las ventanas de mi terminal las tengan.
kjfletch