BASH - Environment Variables - LD_LIBRARY_PATH

LD_LIBRARY_PATH tells the dynamic link loader (ld.so, the program that starts all your applications) where to search for the dynamic shared libraries an application was linked against.

Multiple directories can be listed, separated by a colon (:), and this list is then searched before the compiled-in search path(s), and the standard locations (typically /lib, /usr/lib, …).

LD_LIBRARY_PATH can be used for:

ALERT: Problems with using LD_LIBRARY_PATH include:

  • Security: Directories specified in LD_LIBRARY_PATH get searched before(!) the standard locations.
    • A nasty person could get your application to load a version of a shared library that contains malicious code!
    • That’s one reason why setuid/setgid executables do neglect that variable!
  • Performance: The link loader has to search all the directories specified, until it finds the directory where the shared library resides – for ALL shared libraries the application is linked against!
    • This means a lot of system calls to open(), that will fail with ENOENT (No such file or directory)!
    • If the path contains many directories, the number of failed calls will increase linearly, and you can tell that from the start-up time of the application.
    • If some (or all) of the directories are in an NFS environment, the start-up time of your applications can really get long – and it can slow down the whole system!
  • Inconsistency: This is the most common problem.
    • LD_LIBRARY_PATH forces an application to load a shared library it was not linked against, and that is quite likely not compatible with the original version.
    • This can either be very obvious, i.e. the application crashes, or it can lead to wrong results, if the picked up library not quite does what the original version would have done.
    • Especially the latter is sometimes hard to debug.
  • Non-Fixing of actual issue. Very often it is used as a crutch to fix a problem that could have been avoided by other means; but the actual issue is not fixed, as this workaround becomes relied upon.
    • These settings get dependent on this crutch – and if it is eventually taken away, they start to stumble (i.e. fail to run).

Example Usage

When an executable is run that relies on shared libraries not defined in the global search path, an error similar to the following is displayed:

curl

returns:

ld.so.1: curl: fatal: libgcc_s.so.1: open failed: No such file or directory

Typically this problem is fixed by running ldd(1) on the executable, locating the missing shared libraries, and adding one or more directories to the LD_LIBRARY_PATH environment variable:

ldd /usr/bin/curl

returns:

	linux-vdso.so.1 (0x00007ffd910b0000)
	libcurl.so.4 => /lib/x86_64-linux-gnu/libcurl.so.4 (0x00007ff839fa7000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ff839f8b000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff839f68000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff839d76000)
	libnghttp2.so.14 => /lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007ff839d4d000)
	libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007ff839d2c000)
	librtmp.so.1 => /lib/x86_64-linux-gnu/librtmp.so.1 (0x00007ff839d0a000)
	libssh.so.4 => /lib/x86_64-linux-gnu/libssh.so.4 (0x00007ff839c9c000)
	libpsl.so.5 => /lib/x86_64-linux-gnu/libpsl.so.5 (0x00007ff839c89000)
	libssl.so.1.1 => /lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007ff839bf6000)
	libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007ff839920000)
	libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007ff8398d3000)
	libldap_r-2.4.so.2 => /lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007ff83987b000)
	liblber-2.4.so.2 => /lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007ff83986a000)
	libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007ff83985c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ff83a096000)
        <b>libgcc_s.so.1 =>         (file not found)</b>
           libmp.so.2 =>    /usr/lib/libmp.so.2
	libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007ff8396da000)
	libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007ff839504000)
	libhogweed.so.5 => /lib/x86_64-linux-gnu/libhogweed.so.5 (0x00007ff8394ca000)
	libnettle.so.7 => /lib/x86_64-linux-gnu/libnettle.so.7 (0x00007ff839490000)
	libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007ff83940c000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff839406000)
	libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007ff839329000)
	libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007ff8392f6000)
	libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007ff8392ef000)
	libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007ff8392e0000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007ff8392c4000)
	libsasl2.so.2 => /lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007ff8392a7000)
	libgssapi.so.3 => /lib/x86_64-linux-gnu/libgssapi.so.3 (0x00007ff839262000)
	libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007ff83923f000)
	libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007ff839107000)
	libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007ff8390f1000)
	libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007ff8390ea000)
	libheimntlm.so.0 => /lib/x86_64-linux-gnu/libheimntlm.so.0 (0x00007ff8390de000)
	libkrb5.so.26 => /lib/x86_64-linux-gnu/libkrb5.so.26 (0x00007ff83904b000)
	libasn1.so.8 => /lib/x86_64-linux-gnu/libasn1.so.8 (0x00007ff838fa2000)
	libhcrypto.so.4 => /lib/x86_64-linux-gnu/libhcrypto.so.4 (0x00007ff838f6a000)
	libroken.so.18 => /lib/x86_64-linux-gnu/libroken.so.18 (0x00007ff838f51000)
	libffi.so.7 => /lib/x86_64-linux-gnu/libffi.so.7 (0x00007ff838f45000)
	libwind.so.0 => /lib/x86_64-linux-gnu/libwind.so.0 (0x00007ff838f1b000)
	libheimbase.so.1 => /lib/x86_64-linux-gnu/libheimbase.so.1 (0x00007ff838f07000)
	libhx509.so.5 => /lib/x86_64-linux-gnu/libhx509.so.5 (0x00007ff838eb9000)
	libsqlite3.so.0 => /lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007ff838d90000)
	libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007ff838d55000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff838c06000)

NOTE: This shows the missing library.

export LD_LIBRARY_PATH=/usr/local/lib

Retry:

curl

returns:

curl: try 'curl --help' or 'curl --manual' for more information

NOTE: Using LD_LIBRARY_PATH for this purpose is a complete hack, and ideally this variable should be avoided.