Warum wird mein LD_LIBRARY_PATH nicht gesetzt, um das Terminal zu starten?

8

Ich habe ein Shell-Skript, um einige Umgebungsvariablen einzurichten und jedes Programm zu starten, das ich als Argument einsende:

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

$@

Wenn ich dies zum bashBeispiel zum Aufrufen verwende , funktioniert es:

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

Wenn ich es verwenden , um einen Terminal zu nennen ( xterm, aterm, ...) mein LD_LIBRARY_PATHbekommt ungesetzt:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Warum passiert das? Wie kann ich das aufhalten? (Ich verwende Debian 5.0)

Aktualisieren

Mein Terminal ruft bash nicht als Login auf:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHwird in keiner der Bash-Startdateien angezeigt (außer .bash_history und ~ / .profile ist nicht vorhanden.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
quelle
Rufen diese Startdateien den Befehl "source" oder "." Befehl, um andere Startskripte einzubringen? Wenn ja, kann einer von ihnen der Schuldige sein.
Kevin Panko
Beantwortet Ihre Frage nicht, aber das wirklich Gute wäre, die Notwendigkeit von LD_LIBRARY_PATH loszuwerden (Gründe: 1 2 3 ). Sie können beispielsweise /etc/ld.so.conf bearbeiten oder alle benutzerdefinierten Bibliotheken, die Sie in ~ / local haben, so kompilieren, dass sie wissen, wo sie ihre Bibliotheken finden (siehe die von mir angegebenen Links).
DevSolar

Antworten:

9

Die Terminal-Binärdatei setgidgruppiert sich am wahrscheinlichsten utmp. Setuid- und Setgid-Binärdateien werden LD_LIBRARY_PATHaus Sicherheitsgründen deaktiviert. siehe ld.so(8):

Die erforderlichen gemeinsam genutzten Bibliotheken, die vom Programm benötigt werden, werden in der folgenden Reihenfolge gesucht

  • Verwenden der Umgebungsvariablen LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHfür a.out-Programme). Außer wenn die ausführbare Datei eine setuid / setgid-Binärdatei ist, wird sie in diesem Fall ignoriert.
Teddy
quelle
4

Überprüfen Sie im Terminal (xterm, aterm usw.), wie die Shell aufgerufen wurde: Eine Login-Shell zeigt "-bash" und eine Nicht-Login-Shell zeigt "bash" an, wenn Sie aufrufen echo $0.

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

Eine Login-Bash-Shell liest die folgende Reihenfolge:

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

Überprüfen Sie, ob eine dieser Dateien vorhanden ist und ob sie die Variable zurücksetzen. Sie müssen auch alle Dateien befolgen, die diese Dateien enthalten.

Wenn bash nicht als Login-Shell aufgerufen wird, werden die folgenden Dateien weiterhin gelesen, wenn festgestellt wird, dass es sich um eine interaktive Shell handelt.

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

Eine einfache Möglichkeit, die Art der aufgerufenen Bash-Shell zu bestimmen, besteht darin, Ihr .bash_profile und .bashrc zu definieren und "Login-Shell" bzw. "Interactive-Shell" zu wiederholen.

Sobald Sie die Art der aufgerufenen Shell kennen, können Sie Ihr Skript zur Datei .bashrc oder .bash_profile in Ihrem Home-Verzeichnis hinzufügen. Alternativ können Sie das Zurücksetzen von LD_LIBRARY_PATH deaktivieren.

Beachten Sie, dass Sie Ihr Skript möglicherweise außerhalb davon aufrufen müssen, wenn Ihr .bashrc- oder .bash_profile durch einen ähnlichen Schutz wie den folgenden geschützt ist:

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

fi

Solche Schutzvorrichtungen werden normalerweise platziert, um zu verhindern, dass ein Skript in einer Sitzung mehrmals bezogen wird.

Bearbeiten: Wenn sich herausstellt, dass es mühsam ist, festzustellen, wo die Variable zurückgesetzt wird, und Sie beispielsweise Zugriff auf / etc / profile oder /etc/bash.bashrc haben, können Sie vorübergehend "set -x" am oberen Rand der hinzufügen Skript, um alle Befehle anzuzeigen, die ausgeführt werden. Die Ausgabe ist ziemlich ausführlich, also machen Sie zuerst ein "set -x" in Ihrer Shell und führen Sie einige Befehle aus, damit Sie wissen, was Sie erwartet.


quelle
+1 Danke für die Info. Ich habe mein OP als Antwort auf Ihre Antwort aktualisiert.
kjfletch
Sehen Sie dasselbe Verhalten, wenn Sie durch Eingabe von bash eine neue Bash-Shell auf demselben Terminal eingeben? Übrigens müssen Sie auch Dateien überprüfen, die in /etc/bash.bashrc und / etc / profile aufgerufen werden - eine davon kann die Variable deaktivieren. Alternativ können Sie die set -xDebug-Option verwenden, um einen Speicherauszug von allem zu erhalten, was ab dem Zeitpunkt der Erstellung der Shell ausgeführt wird.
Der set -xSpeicherauszug verweist nicht auf LD_LIBRARY_PATH. Phantom nicht gesetzt.
kjfletch
4

bash verwendet je nach Start unterschiedliche Startskripte. Es gibt sieben verschiedene Möglichkeiten, um es zu starten, aber die wichtigsten sind Login-Shells im Vergleich zu interaktiven Shells ohne Login.

Weitere Informationen finden Sie im Bash-Handbuch . Ich würde vermuten, dass das / etc / profile oder das ~ / .bash_profile etwas unternimmt, um die Variable LD_LIBRARY_PATH zurückzusetzen.


Bearbeiten: Ich denke, Sie haben alles getan, um zu zeigen, dass bash kein Startskript hat, das LD_LIBRARY_PATH deaktiviert. Es ist Zeit, die großen Waffen herauszubringen.

Der folgende Befehl zeigt die gesamte Umgebung an, wenn jeder Prozess gestartet wird, von Bash bis Xterm, und alles andere, was damit zu tun hat. Sie erhalten wahrscheinlich eine große Menge an Ausgabe. Daher ist es eine gute Idee, die Ausgabe in einer Datei zu speichern .

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

Jetzt zeigt die Datei strace_output.txt jeden Systemaufruf Ihres Skripts und jeden untergeordneten Prozess an, und Sie können sehen, welcher Prozess zuletzt LD_LIBRARY_PATH hatte, bevor er entfernt wurde.

Kevin Panko
quelle
2

(Diese Frage ist sehr alt, aber ich bin gerade auf das gleiche Problem gestoßen und dokumentiere die Lösung für die Nachwelt :)

Ich hatte dieses Problem mit dem GNU-Bildschirm (dem Terminal-Multiplexer), aber es kann auch mit einem normalen Terminal passieren. Teddy hatte in meinem Fall recht, Bildschirm hat Setguid gesetzt.

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

Meine Lösung bestand darin, LD_LIBRARY_PATH vor der Ausführung zu speichern und anschließend wiederherzustellen. Also habe ich einen Wrapper ~ / bin / screen erstellt (~ / bin auf PATH setzen) mit folgendem Inhalt:

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

und machte es dann ausführbar mit chmod +x ~/bin/screen. Möglicherweise müssen Sie eine neue Shell öffnen, damit sie den Wrapper aufnimmt.

Dann habe ich folgendes zu ~ / .bashrc hinzugefügt. Denken Sie daran, dass ~ / .bashrc bei jedem Start von bash bezogen wird, im Gegensatz zu ~ / .bash_profile, das nur beim Anmelden (normalerweise beim Start oder beim Anmelden über ssh) bezogen wird.

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

Jetzt sollte screen (oder aterm, xterm, ... ersetzen Sie es einfach oben) $ LD_LIBRARY_PATH wie gewünscht beibehalten.

jdm
quelle
Sie können auch LD_LIBRARY_PATHin .screenrc(anstelle von .bashrc) wiederherstellen : setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"gefolgt vonunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Anscheinend haben Sie eine .bashrc-Datei (oder eine gleichwertige Datei) in Ihrem Home-Verzeichnis, die diese Variable definiert. Ich weiß allerdings nicht viel mehr Details.

Bearbeiten Ok, da das Starten von Bash funktioniert, schätze ich nicht die .bashrc. Aber vielleicht eine andere Konfigurationsdatei, die zufällig auf die gleiche Weise ausgeführt wird, wenn Sie xterm oder aterm starten.

Gnoupi
quelle
Das war mein ursprünglicher Gedanke. Nach langem Suchen ist nichts zu finden. Ich habe den Vorteil, ein sehr sauberes (NEUES) $ HOME zu haben.
kjfletch
0

Die meisten Fenstersysteme erstellen den Anmeldevorgang neu, wenn sie ein Terminalfenster starten, hauptsächlich weil das Terminalfenster das untergeordnete Element des Fenstermanagers und nicht die Startshell wird.

Fügen Sie es also in Ihr .bash_profile oder .bashrc ein, wenn es in einem neuen Fenster angezeigt werden soll.

Eine andere Alternative besteht darin, xterm (zum Beispiel) ein Argument zum Ausführen eines Startskripts zu übergeben. Beenden Sie nicht am Ende dieses Skripts ....

kmarsh
quelle
Ich werde darauf zurückgreifen müssen, denke ich. Ich werde meine Umgebungsvariablen wahrscheinlich sowohl in .xinitrc als auch in .bashrc als Quellcode verwenden, damit meine Terminalfenster sie haben.
kjfletch