- LD_LIBRARY_PATH teilt dem dynamischen Lader mit, wo er nach gemeinsam genutzten Bibliotheken suchen soll, anstatt in den Standard-Systempfaden.
- Seine weltweite Nutzung kann zu Sicherheitslücken, Leistungseinbußen und Inkompatibilitäten führen, die schwer zu beheben sind.
- Es ist vorzuziehen, Alternativen wie -rpath, LD_RUN_PATH oder Wrapper-Skripte zu verwenden, um die Auswirkungen auf bestimmte Anwendungen zu beschränken.
- Die Definition von LD_LIBRARY_PATH nur in spezifischen Tests oder kontrollierten Umgebungen vermeidet versteckte Abhängigkeiten und unvorhersehbares Verhalten.
LD_LIBRARY_PATH ist eine jener Linux-Umgebungsvariablen, mit denen jeder früher oder später in Berührung kommt, die aber nur wenige wirklich verstehen und vor allem häufig falsch verwendet wird. Sobald Probleme mit gemeinsam genutzten Bibliotheken, nicht startfähigen ausführbaren Dateien oder Anwendungen, die eigene Bibliotheken benötigen, auftreten, taucht dieser Name immer wieder auf.
In diesem Artikel erklären wir, was LD_LIBRARY_PATH ist, wie der dynamische Loader intern funktioniert , wann die Verwendung dieser Variable sinnvoll ist und wann man sie besser vermeiden sollte. Wir betrachten praktische Beispiele in Distributionen wie Ubuntu (obwohl dies auf fast jede Distribution anwendbar ist), erläutern die korrekte Konfiguration und stellen außerdem deutlich sauberere und sicherere Alternativen zur permanenten Speicherung dieser Variable im Benutzerprofil vor.
Was ist LD_LIBRARY_PATH und wofür wird es eigentlich verwendet?

In modernen GNU/Linux-Systemen verknüpfen die meisten Programme sich mit Gemeinsame Bibliotheken (.so-Dateien), die beim Start der ausführbaren Datei in den Speicher geladen werden. Die Komponente, die für das Auffinden dieser Bibliotheken zur Laufzeit zuständig ist, ist die dynamisches Ladegerät (gewöhnlich ld.so oder Variationen wie ld-linux-x86-64.so.2 (gemäß der Architektur).
Die Umgebungsvariable LD_LIBRARY_PATH definiert eine Liste von Verzeichnissen Dort sucht der dynamische Lader beim Programmstart nach diesen gemeinsam genutzten Bibliotheken. Es handelt sich um eine durch Doppelpunkte getrennte Liste, etwa so: /ruta/uno:/ruta/dos:/otra/rutaund es wird konsultiert vor den Standardrouten des Systems als /lib o /usr/lib.
Das bedeutet, dass der Loader die Bibliothek in LD_LIBRARY_PATH priorisiert, wenn eine Bibliothek in LD_LIBRARY_PATH denselben Namen wie eine andere Bibliothek in einem Systemverzeichnis hat . Das ist die Stärke dieser Funktion … und gleichzeitig die Ursache vieler Probleme bei unachtsamer Verwendung.
Dieser Mechanismus ist besonders nützlich bei der Arbeit mit nicht standardmäßigen Bibliothekspfaden , zum Beispiel in Nix-ähnlichen Umgebungen, bei Installationen in Benutzerverzeichnissen, bei benutzerdefinierten Versionen von Bibliotheken oder bei Anwendungen, die mit eigenen Abhängigkeiten verpackt sind und nicht auf Systembibliotheken zurückgreifen möchten.
Typische Anwendungsfälle für LD_LIBRARY_PATH

Die Verwendung von LD_LIBRARY_PATH ist nur in sehr spezifischen und kontrollierten Szenarien sinnvoll . Solange man sich an diese Fälle hält, ist es ein sehr nützliches Werkzeug; wenn man es jedoch als Standardlösung für alles einsetzt, wird es früher oder später zu Problemen kommen.
Eine der häufigsten Anwendungen ist die Probieren Sie eine neue Version einer gemeinsam genutzten Bibliothek aus. gegen eine vorkompilierte Anwendung, ohne die Systembibliotheken zu verändern. Wenn Sie beispielsweise eine Entwicklungsversion erstellt haben von libmylib.so In Ihrem Home-Verzeichnis können Sie LD_LIBRARY_PATH so anpassen, dass es nur von Ihrer Testsitzung verwendet wird.
Ein weiteres sehr häufiges Szenario ist das Verschieben von Bibliotheken, um ältere Versionen zu erhalten . Stellen Sie sich vor, Sie möchten eine ältere Version einer Bibliothek für eine Legacy-Anwendung behalten, während der Rest des Systems eine neuere Version verwendet; mit LD_LIBRARY_PATH können Sie diese spezielle Anwendung auf das Verzeichnis verweisen, in dem Sie die ältere Version speichern.
Es wird auch häufig verwendet, um in sich geschlossene und verschiebbare Umgebungen für große Anwendungen einzurichten , in denen der Anbieter seine eigenen Bibliotheken in einem Ordner verpackt, ohne auf Systembibliotheken zurückzugreifen. In diesen Fällen gibt es üblicherweise ein Startskript, das LD_LIBRARY_PATH so anpasst, dass die Anwendung immer ihre eigenen .so-Dateien lädt.
In all diesen Fällen ist der entscheidende Punkt, dass LD_LIBRARY_PATH nur in begrenztem Umfang und auf eine bestimmte Weise verwendet wird , nämlich im Zusammenhang mit einer bestimmten Anwendung oder einer Testumgebung, und nicht als globale Variable, die alles beeinflusst, was ein Benutzer ausführt, oder das gesamte System.
Schritt-für-Schritt-Anleitung zur Konfiguration von LD_LIBRARY_PATH unter Linux

Selbst wenn man die Risiken kennt, will man es trotzdem Definieren Sie LD_LIBRARY_PATH in Ihrer BenutzerumgebungBei Distributionen wie Ubuntu ist es üblich, die Datei zu bearbeiten. ~/.bashrc (Vorausgesetzt, Sie verwenden Bash als Ihre Standard-Shell). Es handelt sich um die Datei, die jedes Mal ausgeführt wird, wenn Sie ein neues interaktives Terminal öffnen.
Öffnen Sie zunächst die Datei. .bashrc mit Ihrem bevorzugten EditorEs wird in vielen Tutorials verwendet. nano Der Einfachheit halber, aber Sie könnten dasselbe tun mit vi, vim oder ein beliebiger Texteditor:
Nano ~ /. Bashrc
Nach dem Öffnen müssen Sie eine Exportzeile hinzufügen, die die Variable festlegt. Wichtig ist hierbei, dass keine Leerzeichen um das Gleichheitszeichen herum stehen, da Bash es sonst falsch interpretiert. Ein korrektes Beispiel wäre:
export LD_LIBRARY_PATH=/home/osboxes/mukul
In diesem Fall weisen wir das System an, bei der Suche nach gemeinsam genutzten Bibliotheken das Verzeichnis `/home/osboxes/mukul` vor den Standardverzeichnissen zu berücksichtigen. Sie können dies durch den Pfad zu Ihren benutzerdefinierten .so-Dateien oder den gewünschten Bibliotheken ersetzen.
Nach dem Speichern der Änderungen und dem Beenden des Editors müssen Sie die Shell-Konfiguration neu laden , damit die neue Umgebungsvariable in der aktuellen Sitzung wirksam wird. Dies geschieht üblicherweise mit:
Quelle ~ /. Bashrc
Wenn Sie überprüfen möchten, ob alles korrekt angewendet wurde, verwenden Sie einfach den Befehl echo Zur Variable: Hier werden Ihnen die Pfade angezeigt, die LD_LIBRARY_PATH aktuell enthält:
echo $LD_LIBRARY_PATH
Wenn die Ausgabezeile das von Ihnen hinzugefügte Verzeichnis enthält, bedeutet dies, dass die Konfiguration korrekt geladen wurde und der dynamische Loader diesen Pfad nun beim Starten von Programmen berücksichtigt.
Wie man zusätzliche Routen hinzufügt, ohne etwas zu beschädigen
Oftmals möchte man den Inhalt von LD_LIBRARY_PATH nicht vollständig ersetzen , sondern einen weiteren Pfad hinzufügen und die bestehenden beibehalten. Dies ist wichtig, wenn bereits andere Bibliotheken konfiguriert sind und Abhängigkeiten zu anderen Anwendungen nicht beeinträchtigt werden sollen.
Um Routen zu "verketten", wird üblicherweise eine Exportform verwendet, die Füge vor der vorherigen Variable ein neues Verzeichnis hinzu.Wenn Sie beispielsweise hinzufügen möchten /home/osboxes/sample Zu dem, was bereits definiert wurde, könnten Sie in Ihrem Schreiben etwa Folgendes schreiben: .bashrc:
export LD_LIBRARY_PATH=/home/osboxes/sample:${LD_LIBRARY_PATH}
Die Reihenfolge ist wichtig, da der dynamische Loader zuerst in /home/osboxes/sample und anschließend in den anderen Verzeichnissen sucht, in denen die Variable bereits existiert. Dadurch können Sie eine Prioritätsbibliothek nur für bestimmte Tests einbinden, ohne die übrige Konfiguration zu verändern.
Nach der Änderung der Datei, denken Sie erneut daran Führe den Befehl "source" aus auf ~/.bashrc um die Änderungen auf das aktuelle Terminal anzuwenden und erneut zu überprüfen mit echo $LD_LIBRARY_PATH dass die neue Route ganz oben in der Liste erscheint.
Die empfehlenswerte Sache ist Vermeiden Sie ständige Änderungen in LD_LIBRARY_PATHJede schlecht ausgeführte Änderung kann sich auf Programme auswirken, die man sich vorher nicht einmal vorstellen kann. Verwenden Sie das "add"-Muster mit der entsprechenden Syntax. ${LD_LIBRARY_PATH} Es hilft, die Konsistenz zu wahren, aber man sollte es nicht übermäßig verwenden.
Wie die Bibliothekssuche funktioniert und warum sie gefährlich sein kann
Hinter LD_LIBRARY_PATH verbirgt sich ein ganz bestimmtes Verhalten des dynamischen Laders: SuchprioritätDie in dieser Variablen angegebenen Pfade werden vor den vorkompilierten Pfaden und Standardverzeichnissen Ihres Systems verarbeitet, wie z. B. /lib, /usr/lib o /usr/lib64.
Das Problem entsteht, wenn diese zusätzlichen Verzeichnisse eine Bibliothek mit demselben Namen wie eine Systembibliothek, aber in einer anderen oder inkompatiblen Version enthalten. Der dynamische Lader wählt dann ohne Zögern die erste Bibliothek aus, die er in LD_LIBRARY_PATH findet, selbst wenn die Anwendung ursprünglich mit einer anderen Version verknüpft war.
Diese Situation birgt die Gefahr verschiedener Konflikte, darunter auch eines schwerwiegenden Sicherheitsrisikos . Gelingt es einem Angreifer, Sie dazu zu bringen, ein Programm mit manipuliertem LD_LIBRARY_PATH auszuführen, besteht die Möglichkeit, dass eine schädliche Bibliothek die legitime Version ersetzt und unerwünschten Code ausführt.
Aus diesem Grund ignorieren die Setuid- oder Setgid-Binärdateien LD_LIBRARY_PATH in der Regel vollständig. Da sie mit erhöhten Rechten ausgeführt werden, wäre die Annahme beliebiger Pfade aus der Benutzerumgebung ein erhebliches Risiko; das System verwirft diese Variable in diesen Fällen einfach.
Abgesehen von der Sicherheit gibt es noch einen weiteren Aspekt: Leistung und Effizienz Eine Sache sollte man beachten: Jedes Verzeichnis, das Sie zu LD_LIBRARY_PATH hinzufügen, zwingt den Loader dazu, Bibliotheken in diesem Pfad zu öffnen, selbst wenn sie dort nicht vorhanden sind. Dies führt zu vielen fehlgeschlagenen Aufrufen von open()die die Fehlermeldung „ENOENT (Datei oder Verzeichnis nicht gefunden)“ zurückgeben und den Start von Anwendungen verlangsamen.
Je mehr Pfade Sie hinzufügen, insbesondere wenn es sich um entfernte Verzeichnisse (NFS) handelt , desto länger dauert der Start Ihrer Programme und desto höher ist die Belastung des Dateisystems. In großen Umgebungen mit Hunderten von Benutzern kann die übermäßige Verwendung von LD_LIBRARY_PATH zu einem unerwarteten Engpass werden.
Typische Probleme: Inkonsistenzen und versteckte Abhängigkeiten
Ein weiterer sehr häufiger Nebeneffekt ist die Inkonsistenz zwischen Binärdateien und Bibliotheken . LD_LIBRARY_PATH kann ein Programm dazu zwingen, eine andere Version einer Bibliothek zu laden als die, mit der es verknüpft wurde, und diese sind auf ABI- oder Verhaltensebene nicht immer zu 100 % kompatibel.
Im besten Fall, wenn eine eindeutige Inkompatibilität vorliegt, startet die Anwendung nicht oder stürzt schnell ab und hinterlässt klare Spuren des Problems. Wirklich gefährlich wird es jedoch, wenn die Bibliothek zwar „mehr oder weniger funktioniert“, dann aber falsche Ergebnisse liefert oder sich so subtil anders verhält, dass die Fehlersuche schwierig ist.
Ein besonders problematischer Anwendungsfall ist die globale Definition von LD_LIBRARY_PATH in Benutzerprofilen oder, noch schlimmer, im Systemprofil. In diesem Fall sind alle in dieser Sitzung ausgeführten Anwendungen dieser Konfiguration ausgesetzt, selbst solche, die nie für die Verwendung dieser zusätzlichen Pfade ausgelegt waren.
Wenn sich diese globalen Pfade ändern oder nicht mehr existieren, können viele Binärdateien plötzlich nicht mehr funktionieren, weil sie, ohne dass es jemand bemerkt hat, begonnen hatten, sich auf diesen "Patch" von LD_LIBRARY_PATH zu verlassen, um ihre Bibliotheken zu finden.
Dies erklärt, warum in vielen professionellen Umgebungen so viel Wert darauf gelegt wird, die Variable nur als einmaliges Testinstrument oder Notfalllösung zu verwenden , niemals aber als langfristig stabilen Konfigurationsmechanismus.
Wie man herausfindet, welche Bibliotheken tatsächlich verwendet werden
Um vollständig zu verstehen, wie sich Ihre Änderungen auf LD_LIBRARY_PATH auswirken, ist es unerlässlich zu wissen Welche Bibliotheken verwendet jede ausführbare Datei?Hier kommen Befehle wie zum Einsatz. ldddie einen recht klaren Überblick über dynamische Verknüpfungen geben.
Der Befehl `ldd` zeigt für eine gegebene Binärdatei an, welche dynamischen Bibliotheken benötigt werden und aus welchem Pfad diese geladen werden. Beispiel:
ldd /usr/bin/file
Sie sehen eine Liste von Zeilen dieses Typs libmagic.so.1 => /usr/lib64/libmagic.so.1, zusammen mit der Entschließung von linux-vdso.so.1, libc.so.6 und das dynamische Ladegerät selbst. Diese Informationen geben Ihnen eine Standbild der wichtigsten Abhängigkeiten der ausführbaren Datei.
Es gibt jedoch Fälle, in denen eine gemeinsam genutzte Bibliothek lädt andere Bibliotheken zur Laufzeit (zum Beispiel durch dlopen()Diese werden in der Ausgabe von ldd nicht berücksichtigt. Um ein vollständigeres Bild zu erhalten, muss untersucht werden, welche .so-Dateien tatsächlich in den Adressraum eines laufenden Prozesses eingebunden sind.
In einigen Solaris-ähnlichen Systemen gibt es den Befehl `pldd` , der die von einem Prozess anhand seiner Prozess-ID (PID) geladenen dynamischen Bibliotheken auflistet. Bei Verwendung in einem Programm wie Bash kann man sehen, wie die von `ldd` aufgelisteten Bibliotheken durch weitere ergänzt werden, beispielsweise durch Zeichenkonvertierungsmodule oder NSS-Module zur Benutzer- und Gruppenauflösung.
In reinem Linux ist pldd nicht immer als Standard-Binärdatei verfügbar, Es gibt Skripte in Perl oder anderen Tools. die die Informationen extrahieren /proc/<PID>/mapsUm einen ähnlichen Effekt zu erzielen, können Sie so überprüfen, ob Ihre LD_LIBRARY_PATH-Einstellungen das Laden unerwarteter Bibliotheken verursacht haben.
Sauberere Wege, um die Abhängigkeit von LD_LIBRARY_PATH zu vermeiden
Die allgemeine Empfehlung beim Umgang mit LD_LIBRARY_PATH ist einfach: Verwenden Sie es so selten wie möglich . Jeder hinzugefügte Pfad birgt das Potenzial für Fehler, Versionskonflikte und Leistungsprobleme. Daher lohnt es sich, robustere Alternativen in Betracht zu ziehen.
Wenn Sie Ihre Anwendungen selbst kompilieren (z. B. nach der Anleitung „Linux From Scratch “), können Sie die Option `-rpath` des Linkers verwenden . Mit dieser Option können Sie den Pfad zu den Bibliotheken, von denen die ausführbare Datei abhängt, direkt in die ausführbare Datei einbetten, sodass die Binärdatei weiß, wo sie diese findet, ohne dass globale Umgebungsvariablen geändert werden müssen.
Ein typisches Beispiel wäre etwa so:
cc -o myprog obj1.o … objn.o -Wl,-rpath=/Pfad/zur/Bibliothek -L/Pfad/zur/Bibliothek -lmylib
Damit fügt der Linker Folgendes hinzu: /Pfad/zur/Bibliothek zum Ausführungspfad der ausführbaren DateiWenn Sie mehrere Routen benötigen, ist die Verwendung der Umgebungsvariablen sehr praktisch. LD_RUN_PATHdie der Linker ebenfalls versteht und die Sie mit einer durch Doppelpunkte getrennten Liste von Verzeichnissen füllen können.
Sie könnten beispielsweise Folgendes tun:
export LD_RUN_PATH=/Pfad/zu/lib1:/Pfad/zu/lib2:/Pfad/zu/lib3
cc -o myprog obj1.o … objn.o -L/Pfad/zu/lib1 -lmylib1 -L/Pfad/zu/lib2 -lmylib2
Nach dem Kompilieren können Sie dies überprüfen mit ldd dass das Binärsystem Es löst alle seine Bibliotheken korrekt auf. ohne sich auf LD_LIBRARY_PATH zu verlassen. Sollten „Nicht gefunden“-Fehler auftreten, müssen Sie die Makefile- und die LD_RUN_PATH-Konfiguration überprüfen.
Wenn eine Neukompilierung nicht möglich ist, können Sie Tools wie chrpath verwenden, um den bereits in der ausführbaren Datei eingebetteten Laufzeitpfad zu ändern. Diese Methode hat jedoch Einschränkungen: Sie können die vorhandene Zeichenkette nur überschreiben, nicht aber erweitern. Und wenn die Binärdatei keinen definierten Laufzeitpfad besitzt, gibt es nichts zu ändern.
Mithilfe von Wrapper-Skripten und durch spezifische Anpassungen über die Kommandozeile
Wenn weder die Verwendung von -rpath noch chrpath möglich ist, können Sie Wrapper-Skripte verwenden , die LD_LIBRARY_PATH nur für eine bestimmte Anwendung anpassen. Dies ist ein deutlich weniger eingreifender Ansatz als die Manipulation des Benutzerprofils.
Ein typischer Wrapper in Shell würde etwa so aussehen:
# / Bin / sh
LD_LIBRARY_PATH=/Pfad/zu/lib1:/Pfad/zu/lib2:/Pfad/zu/lib3
LD_LIBRARY_PATH exportieren
exec /Pfad/zu/bin/myprog «$@»
Bei diesem Ansatz wird die Umgebungsvariable nur für myprog und damit auch für alle von ihm gestarteten Kindprozesse „beeinträchtigt“, nicht aber für andere Befehle, die Sie in Ihrer Sitzung ausführen. Dies ist eine völlig akzeptable Lösung, wenn Sie für eine bestimmte Anwendung gezwungen sind, mit bestimmten Bibliotheksversionen zu arbeiten.
Eine weitere sehr nützliche Option für schnelle Tests ist die Verwendung des Befehls `env` , um `LD_LIBRARY_PATH` nur für eine einzelne Ausführung zu definieren. Zum Beispiel:
env LD_LIBRARY_PATH=/Pfad/zu/lib1:/Pfad/zu/lib2 ./myprog
Auf diese Weise wird die Variable angewendet. nur für diesen Aufruf de myprogUnd wenn der Vorgang abgeschlossen ist, bleibt Ihre Shell intakt, ohne Spuren von seltsamen Pfaden, die den nächsten Befehl, den Sie ausführen, beeinträchtigen könnten.
Von Folgendem sollte man dringend abraten:
export LD_LIBRARY_PATH=/Pfad/zu/lib1:/Pfad/zu/lib2
./myprog
Dieses Muster hinterlässt LD_LIBRARY_PATH für alle nachfolgenden Bestellungen definiert dass Sie es von diesem Terminal aus starten, was Nebenwirkungen verursachen kann, die später nur sehr schwer nachzuverfolgen sind. Für isolierte Tests der Aufruf mit env Es ist viel sauberer.
Bewährte Vorgehensweisen und häufige Fehler, die es zu vermeiden gilt
Eine weithin anerkannte goldene Empfehlung lautet: Definieren Sie LD_LIBRARY_PATH niemals in Anmeldeprofilen.Weder in Benutzer- noch in Systemdateien. Mit anderen Worten: Vermeiden Sie es, es Dateien wie diesen hinzuzufügen. ~/.bash_profile, ~/.profile, /etc/profile oder ähnliches.
Wird eine solch sensible Variable global gesetzt, verwenden alle vom Benutzer gestarteten Anwendungen diese zusätzlichen Pfade, selbst solche, die optimal für die Verwendung mit Systembibliotheken konfiguriert sind. Die Beschränkung des Gültigkeitsbereichs auf bestimmte Skripte oder einmalige Ausführungen ist stets deutlich sicherer.
Es ist ratsam, bei Installationsprogrammen von Drittanbietern vorsichtig zu sein , die Sie während der Installation auffordern, LD_LIBRARY_PATH zu Ihrem Profil hinzuzufügen oder dies global für Sie erledigen. In den meisten Fällen ist dies eine einfache Lösung für den Anbieter, kann aber mittelfristig Probleme in Ihrer Umgebung verursachen.
Wann immer möglich, lohnt es sich, etwas mehr Aufwand zu betreiben und nach sauberen Alternativen zu suchen : den Ausführungspfad der ausführbaren Datei anzupassen, Bibliotheken in einem Standardverzeichnis zu installieren, moderne Paketierungsmechanismen zu verwenden oder die Anwendung mit einem Skript-Wrapper zu umschließen, anstatt die allgemeine Umgebung anzufassen.
Falls Sie gezwungen sind, die Variable zu verwenden, versuchen Sie, die Pfade so kurz und präzise wie möglich zu halten, die Anzahl der Verzeichnisse zu minimieren und Pfade auf entfernten Dateisystemen um jeden Preis zu vermeiden, es sei denn, dies ist unbedingt erforderlich.
Angesichts all dessen bleibt LD_LIBRARY_PATH ein leistungsstarkes, aber auch heikles Werkzeug : Es ist sehr nützlich zum Testen neuer Bibliotheksversionen, zum Verschieben alter .so-Dateien oder zum Erstellen in sich geschlossener Umgebungen für große Anwendungen. Seine unkritische Verwendung birgt jedoch Sicherheitsrisiken, Leistungsprobleme und schwer zu behebende Inkonsistenzen. Um LD_LIBRARY_PATH optimal zu nutzen, ohne es zu einer Falle für Ihr System werden zu lassen, ist es am besten, die Funktionsweise des dynamischen Loaders zu verstehen, Alternativen wie -rpath, LD_RUN_PATH oder Wrapper-Skripte zu verwenden und diese Variable auf sehr spezifische Kontexte zu beschränken.