Pourquoi mon terminal LD_LIBRARY_PATH obtient-il un terminal de lancement non défini?

8

J'ai un script shell pour configurer certaines variables d'environnement et lancer le programme que j'envoie en argument:

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

$@

Quand j'utilise ceci pour appeler bashpar exemple ça marche:

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

Quand je l' utilise pour appeler un terminal ( xterm, aterm...) ma LD_LIBRARY_PATHobtient unset:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Pourquoi cela arrive-t-il? Comment puis-je arrêter cela? (J'utilise Debian 5.0)

Mise à jour

Mon terminal n'appelle pas bash comme identifiant:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHn'apparaît dans aucun des fichiers de démarrage de bash (à l'exception de .bash_history et ~ / .profile n'existe pas.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
la source
Certains de ces fichiers de démarrage appellent-ils la commande "source" ou "." commande pour apporter d'autres scripts de démarrage? Si c'est le cas, l'un d'eux pourrait être le coupable.
Kevin Panko
Ne répond pas à votre question, mais la vraiment bonne chose serait de se débarrasser de la nécessité pour LD_LIBRARY_PATH (raisons: 1 2 3 ). Vous pouvez, par exemple, éditer /etc/ld.so.conf, ou compiler toutes les bibliothèques définies par l'utilisateur que vous avez dans ~ / local de manière à ce qu'elles sachent où trouver leurs bibliothèques (voir les liens que j'ai donnés).
DevSolar

Réponses:

9

Le binaire terminal est le plus susceptible setgidde se regrouper utmp. Les binaires setuid et setgid ne sont pas définis LD_LIBRARY_PATHpour des raisons de sécurité; voir ld.so(8):

Les bibliothèques partagées nécessaires nécessaires au programme sont recherchées dans l'ordre suivant

  • Utilisation de la variable d'environnement LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHpour les programmes a.out). Sauf si l'exécutable est un binaire setuid / setgid, auquel cas il est ignoré.
Teddy
la source
4

Dans le terminal (xterm, aterm, etc.), vérifiez comment le shell a été invoqué: un shell de connexion affichera "-bash" et un shell sans connexion affichera "bash" lorsque vous appelez echo $0.

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

Un shell bash de connexion lira ce qui suit dans l'ordre:

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

Vérifiez si l'un de ces fichiers existe et s'il réinitialise la variable. Vous devrez également suivre tous les fichiers inclus dans ces fichiers.

Si bash n'est pas appelé en tant que shell de connexion, il lira toujours les fichiers ci-dessous s'il est déterminé qu'il s'agit d'un shell interactif.

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

Un moyen simple de déterminer le type de shell bash appelé est de définir votre .bash_profile et .bashrc, et echo "Login shell" et "Interactive shell" respectivement.

Une fois que vous connaissez le type de shell invoqué, vous avez la possibilité d'ajouter votre script au fichier .bashrc ou .bash_profile de votre répertoire personnel. Vous pouvez également désactiver la réinitialisation de LD_LIBRARY_PATH.

Notez que si votre .bashrc ou .bash_profile est protégé par un garde similaire à celui ci-dessous, vous devrez peut-être appeler votre script en dehors:

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

fi

Ces gardes sont normalement placées pour empêcher qu'un script soit sourcé plusieurs fois dans une session.

Edit: S'il s'avère que Tedius recherche où la variable est réinitialisée et que vous avez accès à / etc / profile ou /etc/bash.bashrc par exemple, vous pouvez temporairement ajouter "set -x" près du haut de la script pour voir toutes les commandes qui sont exécutées. La sortie sera assez verbeuse, donc commencez par "set -x" dans votre shell et exécutez quelques commandes pour savoir à quoi vous attendre.


la source
+1 Merci pour l'info. J'ai mis à jour mon PO en réponse à votre réponse.
kjfletch
Voyez-vous le même comportement si vous entrez un nouveau shell bash sur le même terminal en tapant bash? De plus, vous devrez également vérifier les fichiers qui sont appelés à partir de /etc/bash.bashrc et / etc / profile - l'un d'entre eux pourrait annuler la variable. Alternativement, utilisez l' set -xoption de débogage pour obtenir un vidage de tout ce qui est fait à partir du moment où le shell est créé.
Le set -xvidage ne fait aucune référence à LD_LIBRARY_PATH. Fantôme désarmé.
kjfletch
4

bash utilisera différents scripts de démarrage selon la façon dont il est démarré. Il existe sept façons différentes de le démarrer, mais les plus importantes sont les shells de connexion et les shells interactifs sans connexion.

Consultez le manuel bash pour plus de détails. Je soupçonne que le profil / etc / ou le ~ / .bash_profile fait quelque chose pour réinitialiser la variable LD_LIBRARY_PATH.


Edit: Je pense que vous avez fait tout ce que vous pouvez raisonnablement pour montrer que bash n'a pas de script de démarrage qui désactive LD_LIBRARY_PATH. Il est temps de sortir les gros canons.

La commande suivante affichera l'environnement entier au démarrage de chaque processus, de bash à xterm, et tout ce qui pourrait être impliqué - vous obtiendrez probablement une grande quantité de sortie, donc enregistrer la sortie dans un fichier est une bonne idée .

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

Maintenant, le fichier strace_output.txt affichera chaque appel système effectué par votre script et chaque processus enfant, et vous pourrez voir quel processus était le dernier à avoir LD_LIBRARY_PATH avant sa suppression.

Kevin Panko
la source
2

(Cette question est très ancienne, mais je viens de rencontrer le même problème et je documente la solution pour la postériorité :)

J'ai eu ce problème avec l'écran GNU (le multiplexeur de terminaux), mais cela peut aussi bien arriver avec un terminal normal. Teddy avait raison dans mon cas, l'écran a défini un guide.

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

Ma solution était de sauvegarder LD_LIBRARY_PATH avant l'exécution et de le restaurer ensuite. J'ai donc créé un wrapper ~ / bin / screen (mettre ~ / bin sur PATH), avec le contenu suivant:

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

puis rendu exécutable avec chmod +x ~/bin/screen. Vous devrez peut-être ouvrir un nouveau shell pour qu'il récupère le wrapper.

Ensuite, j'ai ajouté ce qui suit à ~ / .bashrc. N'oubliez pas que ~ / .bashrc est sourcé à chaque démarrage de bash, contrairement à ~ / .bash_profile qui ne provient que de la connexion (généralement au démarrage ou lorsque vous vous connectez via 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

Maintenant, screen (ou aterm, xterm, ... remplacez-le ci-dessus) devrait conserver $ LD_LIBRARY_PATH comme vous le souhaitez.

jdm
la source
Vous pouvez également restaurer LD_LIBRARY_PATHdans .screenrc(au lieu de .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"suivi deunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Il semble que vous ayez un fichier .bashrc (ou équivalent) dans votre répertoire personnel qui définit cette variable. Je ne connais cependant pas beaucoup plus de détails.

Edit Ok, depuis que bash fonctionne, je suppose que ce n'est pas le .bashrc. Mais peut-être un autre fichier de configuration qui se trouve être exécuté de la même manière, lorsque vous démarrez xterm ou aterm.

Gnoupi
la source
C'était ma pensée originale. Après de longues recherches, il n'y a rien à trouver. J'ai l'avantage d'avoir un (NOUVEAU) $ HOME très propre.
kjfletch
0

La plupart des systèmes de fenêtrage recréent le processus de connexion lorsqu'ils lancent une fenêtre de terminal, principalement parce que la fenêtre de terminal devient l'enfant du gestionnaire de fenêtrage et non le shell de lancement.

Alors, mettez-le dans votre .bash_profile ou .bashrc si vous voulez qu'il apparaisse dans une nouvelle fenêtre.

Une autre alternative consiste à remettre à xterm (par exemple) un argument pour exécuter un script de démarrage. Ne quittez pas à la fin de ce script ....

kmarsh
la source
Je vais devoir y recourir, je pense. Je vais probablement trouver mes variables d'environnement dans les deux .xinitrc pour que mon gestionnaire de fenêtres les ait, et dans .bashrc pour que mes fenêtres de terminal les aient.
kjfletch