Linux Professional Institute Learning Logo.
Pasar al contenido principal
  • Inicio
    • Todos los recursos
    • LPI Learning Materials
    • Conviértete en colaborador
    • Publishing Partners
    • Conviértase en un Publishing Partner
    • Acerca de nosotros
    • FAQ
    • Colaboradores
    • Roadmap
    • Contáctenos
  • LPI.org
102.3 Lección 1
Tema 101: Arquitectura del Sistema
101.1 Determinar y configurar los ajustes de hardware
  • 101.1 Lección 1
101.2 Arranque del sistema
  • 101.2 Lección 1
101.3 Cambiar los niveles de ejecución / objetivos de arranque y apagar o reiniciar el sistema
  • 101.3 Lección 1
Tema 102: Instalación de Linux y gestión de paquetes
102.1 Diseño del esquema de particionado del disco duro duro
  • 102.1 Lección 1
102.2 Instalar un gestor de arranque
  • 102.2 Lección 1
102.3 Gestión de librerías compartidas
  • 102.3 Lección 1
102.4 Gestión de paquetes Debian
  • 102.4 Lección 1
102.5 Gestión de paquetes RPM y YUM
  • 102.5 Lección 1
102.6 Linux como sistema virtualizado
  • 102.6 Lección 1
Tema 103: Comandos GNU y Unix
103.1 Trabajar desde la línea de comandos
  • 103.1 Lección 1
  • 103.1 Lección 2
103.2 Procesar secuencias de texto usando filtros
  • 103.2 Lección 1
103.3 Administración básica de archivos
  • 103.3 Lección 1
  • 103.3 Lección 2
103.4 Uso de secuencias de texto, tuberías y redireccionamientos
  • 103.4 Lección 1
  • 103.4 Lección 2
103.5 Crear, supervisar y matar procesos
  • 103.5 Lección 1
  • 103.5 Lección 2
103.6 Modificar la prioridad de ejecución de los procesos
  • 103.6 Lección 1
103.7 Realizar búsquedas en archivos de texto usando expresiones regulares
  • 103.7 Lección 1
  • 103.7 Lección 2
103.8 Edición básica de archivos
  • 103.8 Lección 1
Tema 104: Dispositivos, sistemas de archivos Linux y el estándar de jerarquía de archivos
104.1 Creación de particiones y sistemas de archivos
  • 104.1 Lección 1
104.2 Mantener la integridad de los sistemas de archivos
  • 104.2 Lección 1
104.3 Controlar el montaje y desmontaje de los sistemas de archivos
  • 104.3 Lección 1
104.5 Administración de los permisos y los propietarios de los archivos
  • 104.5 Lección 1
104.6 Crear y cambiar enlaces duros y simbólicos
  • 104.6 Lección 1
104.7 Encontrar archivos de sistema y ubicar archivos en el lugar correspondiente
  • 104.7 Lección 1
How to get certified
  1. Tema 102: Instalación de Linux y gestión de paquetes
  2. 102.3 Gestión de librerías compartidas
  3. 102.3 Lección 1

102.3 Lección 1

Certificación:

LPIC-1

Versión:

5.0

Tema:

102 Instalación de Linux y Administración de Paquetes

Objetivo:

102.3 Administrar bibliotecas compartidas

Lección:

1 de 1

Introducción

En esta lección discutiremos sobre bibliotecas compartidas (shared libraries), también conocidas como objetos compartidos (shared objects): partes de código compilado y reutilizable como funciones o clases, que varios programas utilizan de manera recurrente.

Para comenzar, explicaremos qué son las bibliotecas compartidas, cómo identificarlas y dónde se encuentran. A continuación, veremos cómo configurar sus ubicaciones de almacenamiento. Finalmente, mostraremos cómo buscar las bibliotecas compartidas de las que depende un programa en particular.

Concepto de bibliotecas compartidas

Al igual que sus contrapartes físicas, las bibliotecas de software son colecciones de código que están destinadas a ser utilizadas por muchos programas diferentes; así como las bibliotecas físicas guardan libros y otros recursos para ser utilizados por muchas personas diferentes.

Para construir un archivo ejecutable a partir del código fuente de un programa, son necesarios dos pasos importantes. Primero, el compilador convierte el código fuente en código de máquina que se almacena en los llamados object files. En segundo lugar, el linker combina los archivos de objetos y los vincula a las bibliotecas para generar el archivo ejecutable final. Este enlace puede hacerse statically (estáticamente) o dynamically (dinámicamente). Dependiendo del método que utilicemos, hablaremos de bibliotecas estáticas o, en caso de vinculación dinámica, de bibliotecas compartidas. Expliquemos sus diferencias.

Bibliotecas estáticas

Una biblioteca estática se fusiona con el programa en el momento del enlace. Una copia del código de la biblioteca se incrusta en el programa y se convierte en parte de él. Por lo tanto, el programa no tiene dependencias de la biblioteca en tiempo de ejecución porque el programa ya contiene el código de la biblioteca. No tener dependencias puede verse como una ventaja, ya que no tiene que preocuparse por asegurarse de que las bibliotecas utilizadas siempre estén disponibles. En el lado negativo, los programas vinculados estáticamente son más pesados.

Bibliotecas compartidas (o dinámicas)

En el caso de las bibliotecas compartidas, el enlazador simplemente se encarga de que el programa haga referencia a las bibliotecas correctamente. Sin embargo, el vinculador no copia ningún código de biblioteca en el archivo del programa. Sin embargo, en tiempo de ejecución, la biblioteca compartida debe estar disponible para satisfacer las dependencias del programa. Este es un enfoque económico para administrar los recursos del sistema, ya que ayuda a reducir el tamaño de los archivos de programa y solo se carga una copia de la biblioteca en la memoria, incluso cuando es utilizada por varios programas.

Convenciones de nomenclatura de archivos de objetos compartidos

El nombre de una biblioteca compartida, también conocida como soname, sigue un patrón que se compone de tres elementos:

  • Nombre de la biblioteca (normalmente precedido por lib)

  • so (que significa “objeto compartido”)

  • Número de versión de la biblioteca

Por ejemplo: libpthread.so.0

Por el contrario, los nombres de las bibliotecas estáticas terminan en .a, p. ej. libpthread.a.

Note

Debido a que los archivos que contienen bibliotecas compartidas deben estar disponibles cuando se ejecuta el programa, la mayoría de los sistemas Linux contienen bibliotecas compartidas. Dado que las bibliotecas estáticas solo se requieren en un archivo dedicado cuando se vincula un programa, es posible que no estén presentes en un sistema de usuario final.

glibc (biblioteca GNU C) es un buen ejemplo de una biblioteca compartida. En un sistema Debian GNU/Linux 9.9, su archivo se llama libc.so.6. Tales nombres de archivo bastante generales son normalmente enlaces simbólicos que apuntan al archivo real que contiene una biblioteca, cuyo nombre contiene el número de versión exacto. En el caso de glibc, este enlace simbólico se ve así:

$ ls -l /lib/x86_64-linux-gnu/libc.so.6
lrwxrwxrwx 1 root root 12 feb  6 22:17 /lib/x86_64-linux-gnu/libc.so.6 -> libc-2.24.so

Este patrón de hacer referencia a archivos de biblioteca compartida nombrados por una versión específica por nombres de archivo más generales es una práctica común.

Otros ejemplos de bibliotecas compartidas incluyen libreadline (que permite a los usuarios editar líneas de comando a medida que se escriben e incluye soporte para los modos de edición Emacs y vi), libcrypt (que contiene funciones relacionadas con el cifrado, el hash y la codificación) , o libcurl (que es una biblioteca de transferencia de archivos multiprotocolo).

Las ubicaciones comunes para las bibliotecas compartidas en un sistema Linux son:

  • /lib

  • /lib32

  • /lib64

  • /usr/lib

  • /usr/local/lib

Note

El concepto de bibliotecas compartidas no es exclusivo de Linux. En Windows, por ejemplo, se denominan DLL, que significa dynamic linked libraries (bibliotecas vinculadas dinámicamente).

Configuración de rutas de bibliotecas compartidas

Las referencias contenidas en los programas vinculados dinámicamente se resuelven mediante el vinculador dinámico (ld.so o ld-linux.so) cuando se ejecuta el programa. El vinculador dinámico busca bibliotecas en varios directorios. Estos directorios están especificados por la ruta de la biblioteca. La ruta de la biblioteca se configura en el directorio /etc, es decir, en el archivo /etc/ld.so.conf y, más común hoy en día, en archivos que residen en el directorio /etc/ld.so.conf.d. Normalmente, el primero incluye una sola línea include para los archivos *.conf en el segundo:

$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

El directorio /etc/ld.so.conf.d contiene archivos *.conf:

$ ls /etc/ld.so.conf.d/
libc.conf  x86_64-linux-gnu.conf

Estos archivos *.conf deben incluir las rutas absolutas a los directorios de las bibliotecas compartidas:

$ cat /etc/ld.so.conf.d/x86_64-linux-gnu.conf
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

El comando ldconfig se encarga de leer estos archivos de configuración, creando el conjunto de enlaces simbólicos antes mencionados que ayudan a localizar las bibliotecas individuales y finalmente a actualizar el archivo de caché /etc/ld.so.cache. Por lo tanto, ldconfig debe ejecutarse cada vez que se agregan o actualizan archivos de configuración.

Las opciones útiles para ldconfig son:

-v, --verbose

Muestra los números de versión de la biblioteca, el nombre de cada directorio y los enlaces que se crean:

$ sudo ldconfig -v
/usr/local/lib:
/lib/x86_64-linux-gnu:
    libnss_myhostname.so.2 -> libnss_myhostname.so.2
	libfuse.so.2 -> libfuse.so.2.9.7
	libidn.so.11 -> libidn.so.11.6.16
	libnss_mdns4.so.2 -> libnss_mdns4.so.2
	libparted.so.2 -> libparted.so.2.0.1
	(...)

Así podemos ver, por ejemplo, cómo se vincula libfuse.so.2 con el archivo de objeto compartido real libfuse.so.2.9.7.

-p, --print-cache

Imprime las listas de directorios y bibliotecas candidatas almacenadas en la caché actual:

$ sudo ldconfig -p
1094 libs found in the cache `/etc/ld.so.cache'
    libzvbi.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi.so.0
	libzvbi-chains.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi-chains.so.0
	libzmq.so.5 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzmq.so.5
	libzeitgeist-2.0.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzeitgeist-2.0.so.0
	(...)

Observe cómo la cache usa el nombre completo del soname en el enlace:

$ sudo ldconfig -p |grep libfuse
	  libfuse.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libfuse.so.2

Si hacemos una lista larga de /lib/x86_64-linux-gnu/libfuse.so.2, encontraremos la referencia al archivo de objeto compartido real libfuse.so.2.9.7 que está almacenado en el mismo directorio:

$ ls -l /lib/x86_64-linux-gnu/libfuse.so.2
lrwxrwxrwx 1 root root 16 Aug 21  2018 /lib/x86_64-linux-gnu/libfuse.so.2 -> libfuse.so.2.9.7
Note

Como requiere acceso de escritura a /etc/ld.so.cache (propiedad de root), debe ser root o usar sudo para invocar ldconfig. Para obtener más información sobre los interruptores ldconfig, consulte su página de manual.

Además de los archivos de configuración descritos anteriormente, la variable de entorno LD_LIBRARY_PATH se puede usar para agregar nuevas rutas para bibliotecas compartidas temporalmente. Está formado por un conjunto de directorios separados por dos puntos (:) donde se buscan las bibliotecas. Para agregar, por ejemplo, /usr/local/mylib a la ruta de la biblioteca en la sesión de shell actual, puede teclear:

$ LD_LIBRARY_PATH=/usr/local/mylib

Ahora puede verificar su valor:

$ echo $LD_LIBRARY_PATH
/usr/local/mylib

Para agregar /usr/local/mylib a la ruta de la biblioteca en la sesión de shell actual y exportarlo a todos los procesos secundarios generados desde ese shell, debe usar el siguiente comando:

$ export LD_LIBRARY_PATH=/usr/local/mylib

Para eliminar la variable de entorno LD_LIBRARY_PATH, simplemente utilice el siguiente comando:

$ unset LD_LIBRARY_PATH

Para que los cambios sean permanentes, usar el siguiente comando.

export LD_LIBRARY_PATH=/usr/local/mylib

en uno de los scripts de inicialización de Bash como /etc/bash.bashrc o ~/.bashrc.

Note

LD_LIBRARY_PATH es para las bibliotecas compartidas lo que PATH es para los ejecutables. Para obtener más información sobre variables de entorno y configuración de shell, consulte las lecciones respectivas.

Buscando las dependencias de un ejecutable particular

Para buscar las bibliotecas compartidas requeridas por un programa específico, use el comando ldd seguido de la ruta absoluta al programa. El resultado muestra la ruta del archivo de la biblioteca compartida, así como la dirección de memoria hexadecimal en la que se carga:

$ ldd /usr/bin/git
    linux-vdso.so.1 =>  (0x00007ffcbb310000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f18241eb000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f1823fd1000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f1823db6000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1823b99000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f1823991000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f18235c7000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f182445b000)

Del mismo modo, usamos ldd para buscar las dependencias de un objeto compartido:

$ ldd /lib/x86_64-linux-gnu/libc.so.6
	/lib64/ld-linux-x86-64.so.2 (0x00007fbfed578000)
	linux-vdso.so.1 (0x00007fffb7bf5000)

Con la opción -u (o --unused) ldd imprime las dependencias directas no utilizadas (si existen):

$ ldd -u /usr/bin/git
Unused direct dependencies:
	/lib/x86_64-linux-gnu/libz.so.1
	/lib/x86_64-linux-gnu/libpthread.so.0
	/lib/x86_64-linux-gnu/librt.so.1

La razón de las dependencias no utilizadas está relacionada con las opciones utilizadas por el vinculador al construir el binario. Aunque el programa no necesita una biblioteca no utilizada, todavía estaba vinculado y etiquetado como NEEDED en la información sobre el archivo objeto. Puede investigar esto usando comandos como readelf u objdump, que pronto usará en el ejercicio de exploración.

Ejercicios Guiados

  1. Divida los siguientes nombres de bibliotecas compartidas en sus partes:

    Nombre completo del archivo Nombre de la biblioteca so sufijo Número de versión

    linux-vdso.so.1

    libprocps.so.6

    libdl.so.2

    libc.so.6

    libsystemd.so.0

    ld-linux-x86-64.so.2

  2. Ha desarrollado un software y desea agregar un nuevo directorio de biblioteca compartida a su sistema (/opt/lib/mylib). Escriba su ruta absoluta en un archivo llamado mylib.conf.

    • ¿En qué directorio debe almacenar este archivo?

    • ¿Qué comando debe ejecutar para que los cambios sean totalmente efectivos?

  3. ¿Qué comando usaría para listar las bibliotecas compartidas requeridas por kill?

Ejercicios Exploratorios

  1. objdump es una utilidad de línea de comandos que muestra información de archivos de objetos. Compruebe si está instalado en su sistema con which objdump. Si no es así, instálelo.

    • Use objdump con -p (o --private-headers) y grep para imprimir las dependencias de glibc:

    • Use objdump con -p (o --private-headers) y grep para imprimir el soname de glibc:

    • Use objdump con -p (o --private-headers) y grep para imprimir las dependencias de Bash:

Resumen

En esta lección aprendimos:

  • ¿Qué es una biblioteca compartida (o dinámica)?

  • Las diferencias entre bibliotecas compartidas y estáticas.

  • Los nombres de las bibliotecas compartidas (sonames).

  • Las ubicaciones preferidas para bibliotecas compartidas en un sistema Linux, como /lib o /usr/lib.

  • El propósito del enlazador dinámico ld.so (o ld-linux.so).

  • ¿Cómo configurar rutas compartidas de la biblioteca mediante archivos en /etc/ como ld.so.conf o los del directorio ld.so.conf.d?

  • ¿Cómo configurar rutas de biblioteca compartidas mediante la variable de entorno LD_LIBRARY_PATH?

  • ¿Cómo buscar dependencias de bibliotecas ejecutables y compartidas?

Comandos utilizados en esta lección:

ls

Lista el contenido de un directorio.

cat

Concatena archivos e imprime en la salida estándar.

sudo

Hace que el superusuario ejecute el comando con privilegios administrativos.

ldconfig

Configura enlaces de tiempo de ejecución del vinculador dinámico.

echo

Muestra el valor de la variable de entorno.

export

Valor de exportación de la variable de entorno a shells secundarios.

unset

Elimina variables de entorno.

ldd

Imprime dependencias de objetos compartidos de un programa.

readelf

Muestra información sobre archivos ELF (ELF significa executable and linkable format).

objdump

Imprime información de archivos de objetos.

Respuestas a los ejercicios guiados

  1. Divida los siguientes nombres de bibliotecas compartidas en sus partes:

    Nombre completo del archivo Nombre de la biblioteca so sufijo Número de versión

    linux-vdso.so.1

    linux-vdso

    so

    1

    libprocps.so.6

    libprocps

    so

    6

    libdl.so.2

    libdl

    so

    2

    libc.so.6

    libc

    so

    6

    libsystemd.so.0

    libsystemd

    so

    0

    ld-linux-x86-64.so.2

    ld-linux-x86-64

    so

    2

  2. Ha desarrollado un software y desea agregar un nuevo directorio de biblioteca compartida a su sistema (/opt/lib/mylib). Escriba su ruta absoluta en un archivo llamado mylib.conf.

    • ¿En qué directorio debe almacenar este archivo?

      /etc/ld.so.conf.d

    • ¿Qué comando debe ejecutar para que los cambios sean totalmente efectivos?

      ldconfig

  3. ¿Qué comando usaría para listar las bibliotecas compartidas requeridas por kill?

    ldd /bin/kill

Respuestas a ejercicios exploratorios

  1. objdump es una utilidad de línea de comandos que muestra información de archivos de objetos. Compruebe si está instalado en su sistema con which objdump. Si no es así, instálelo.

    • Use objdump con el -p (o --private-headers) y grep para imprimir las dependencias de glibc:

      objdump -p /lib/x86_64-linux-gnu/libc.so.6 | grep NEEDED

    • Use objdump con el -p (o --private-headers) y grep para imprimir el soname de glibc:

      objdump -p /lib/x86_64-linux-gnu/libc.so.6 | grep SONAME

    • Use objdump con el -p (o --private-headers) y grep para imprimir las dependencias de Bash:

      objdump -p /bin/bash | grep NEEDED

Linux Professional Insitute Inc. Todos los derechos reservados. Visite el sitio web de Learning Materials: https://learning.lpi.org
Este trabajo está registrado bajo la Licencia Internacional Creative Commons Attribution-NonCommercial-NoDerivatives 4.0

Siguiente lección

102.5 Gestión de paquetes RPM y YUM (102.5 Lección 1)

Leer la próxima lección

Linux Professional Insitute Inc. Todos los derechos reservados. Visite el sitio web de Learning Materials: https://learning.lpi.org
Este trabajo está registrado bajo la Licencia Internacional Creative Commons Attribution-NonCommercial-NoDerivatives 4.0

LPI es una organización sin fines de lucro.

© 2023 Linux Professional Institute (LPI) es la organización global de certificación y apoyo académico para profesionales de código abierto. Con más de 200,000 titulares de certificación, es el primer y más grande organismo de certificación no comercial del mundo para Linux y Open Source. LPI cuenta con profesionales certificados en más de 180 países, realiza exámenes en varios idiomas y tiene cientos de socios de capacitación.

Nuestro propósito es hacer que las oportunidades económicas y creativas estén disponibles para todos, haciendo que el conocimiento de código abierto y la certificación sea universalmente accesible.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Contáctenos
  • Política de privacidad y cookies

¿Detecta un error o desea ayudar a mejorar esta página? Por favor háznoslo saber.

© 1999–2023 The Linux Professional Institute Inc. Todos los derechos reservados.