Bash Installer

Instalador Auto-contenido en Bash: Guía Paso a Paso

En este tutorial, aprenderás cómo crear un script de instalador auto-contenido que empaquete cualquier ejecutable y sus dependencias en un solo script. Este script puede ser distribuido a los usuarios para facilitar la instalación en diferentes sistemas, sin necesidad de recursos o descargas externas.

¿Por qué un Instalador Auto-contenido?

Un script de instalador auto-contenido tiene varias ventajas:

  • Portabilidad: Puede ser distribuido fácilmente sin preocuparse por archivos o dependencias faltantes.
  • Fácil de usar: Los usuarios solo necesitan ejecutar un script para instalar la herramienta.
  • Eficiencia: Todo lo necesario para la instalación está incrustado directamente en el script.

Veamos el proceso para crear un instalador de este tipo.

Paso 1: Configurar la Estructura del Proyecto

Utilizaremos una estructura de proyecto simple para demostrar cómo empaquetar una herramienta, asumiendo que ya tienes un ejecutable compilado en un directorio dist/. Aquí tienes un ejemplo de la estructura:

myproject/
│
├── dist/ # Ejecutable compilado
│ └── mytool # El ejecutable a instalar
├── installer/ # Plantillas del instalador
│ └── installer.sh # Script base del instalador
├── build/ # Directorio de salida del build
├── bin/ # Donde se colocará el instalador final
└── Makefile # Automatiza el proceso de empaquetado e instalación

Paso 2: Makefile

Makefile automatiza el proceso de empaquetar la herramienta en un archivo tar y de incrustar ese archivo en un script de instalador.

Puntos Clave:

compress: Empaqueta el ejecutable (mytool) desde dist/ en un archivo tar y lo añade al script del instalador.
clean: Limpia los archivos temporales creados durante el proceso de construcción.
build: Un objetivo que automatiza todo el proceso de empaquetado y preparación del instalador.

Paso 3: Script del Instalador

El script del instalador (installer/installer.sh) extraerá el archivo tar incrustado y configurará la herramienta en la máquina del usuario.

Puntos Clave del Script del Instalador:

  1. Comprobación de Sudo: Asegura que el script se ejecute con privilegios de root (sudo).
  2. Comprobación de Disponibilidad de Herramientas: Verifica que las herramientas esenciales como tar, cat, tail y mkdir estén disponibles.
  3. Desempaquetado del Archivo: El marcador __ARCHIVE__ es un marcador de posición donde se añade el archivo tar. El script identifica dónde comienza el archivo y lo extrae.
  4. Enlace Simbólico: Crea un enlace simbólico en /usr/local/bin para que la herramienta pueda ejecutarse desde cualquier parte del sistema.
  5. Permisos: Establece los permisos adecuados para que el ejecutable sea accesible y ejecutable.

Paso 4: Ejecutar el Instalador

Después de construir el instalador, tendrás un archivo llamado setup.sh en el directorio bin/. Para instalar la herramienta en cualquier sistema:

  1. Asegúrate de que el script tenga los permisos apropiados:
chmod +x setup.sh

2. Ejecuta el script con sudo para instalar la herramienta:

sudo ./setup.sh

Esto instalará el ejecutable mytool en /usr/local/bin, haciéndolo accesible globalmente.

Paso 5: Distribuir Tu Instalador

La ventaja de este instalador auto-contenido es que puede ser distribuido como un único archivo (setup.sh). Como el script incluye la herramienta real (empaquetada como un archivo tar), los usuarios solo necesitan descargar y ejecutar el script para instalar la herramienta en su sistema.

Explicación

Empaquetado del Binario

Para empaquetar el binario o ejecutable en el script, usamos un proceso que lo comprime en un archivo tarball (un archivo .tar o .tar.xz) y luego lo añadimos al final del script Bash. Esto lo hacemos en el Makefile.

compress:
@echo "[*] Empaquetando el ejecutable y las dependencias"
@mkdir -p $(buildPath)
@cp $(distPath)/$(tool) $(buildPath)/$(tool)
@cd $(buildPath); tar cJf $(tarName) $(tool)
@cp $(installer_template) $(installer)
@echo "[*] Añadiendo el binario al instalador"
@cat $(tarFile) >> $(installer)
@chmod a+x $(installer)
@mv $(installer) $(binPath)

1. Copiar el binario (mytool) desde el directorio de distribución (dist/) al directorio de construcción (build/).

@cp $(distPath)/$(tool) $(buildPath)/$(tool)

2. Crear un archivo tarball comprimido (tar.xz) que contiene el binario:

@cd $(buildPath); tar cJf $(tarName) $(tool)

Esto crea un archivo comprimido tool.tar.xz que contiene el binario mytool.

3. Añadir el archivo tarball al final del script de instalación:


@cat $(tarFile) >> $(installer)

Aquí, el contenido del archivo comprimido (tool.tar.xz) se concatena al final del archivo del instalador (setup.sh).

4. Dar permisos de ejecución al instalador:

@chmod a+x $(installer)

Cómo el Script Bash Usa el Binario Incrustado

Una vez que el archivo comprimido está añadido al script, el siguiente paso es extraer ese binario durante la ejecución del script de instalación. Esto es clave para que el script pueda instalar el binario en la ubicación deseada en el sistema.

Marcador ARCHIVE:

En el script Bash, usamos un marcador especial llamado ARCHIVE que indica dónde termina el código del instalador y dónde empieza el archivo binario incrustado.

__ARCHIVE__

Todo lo que viene después de este marcador es el contenido comprimido (en este caso, el archivo tar.xz).

Cómo Se Extrae el Binario del Script:

El script usa herramientas como awk y tail para identificar dónde comienza el archivo binario (después del marcador ARCHIVE) y extraerlo.

Veamos esta parte del script:

ARCHIVE=$(awk '/^__ARCHIVE__/ {print NR+1; exit 0; }' "$0")
tail -n+${ARCHIVE} "$0" | tar xJv -C /usr/local

Identificar la Línea de Inicio del Archivo Comprimido:

ARCHIVE=$(awk '/^__ARCHIVE__/ {print NR+1; exit 0; }' "$0")

Aquí, awk busca la línea que contiene ARCHIVE y devuelve el número de la siguiente línea (donde comienza el archivo binario comprimido). La variable ARCHIVE ahora contiene ese número de línea.

Extraer el Archivo desde el Script:

tail -n+${ARCHIVE} "$0" | tar xJv -C /usr/local

Usamos tail -n+${ARCHIVE} para obtener todas las líneas del script a partir de esa línea (es decir, todo lo que está después de ARCHIVE). Este contenido es el archivo comprimido. Luego, lo descomprimimos usando tar y lo extraemos en el directorio /usr/local.

Instalación y Enlace Simbólico

Después de extraer el binario, el script:

1. Copia el binario al directorio de destino (/usr/local/mytool).
2. Crea un enlace simbólico en /usr/local/bin para que el ejecutable esté disponible globalmente en el sistema.

chmod 755 "$APP_DIR/$APP"
ln -s "$APP_DIR/$APP" "$DESTINATION/$APP"

chmod 755: Establece los permisos adecuados para el binario, haciéndolo ejecutable.
ln -s: Crea un enlace simbólico en /usr/local/bin para que puedas ejecutar mytool desde cualquier terminal escribiendo su nombre.

Dependencias de Linux Requeridas:

  • 1. bash: El script del instalador está escrito en Bash, por lo que es necesario tener Bash instalado y disponible en el sistema. Casi todas las distribuciones de Linux lo incluyen de forma predeterminada.
  • 2. tar:Se utiliza para descomprimir el archivo empaquetado (tar.xz). Es una herramienta estándar en la mayoría de los sistemas Unix y Linux, y es esencial para manejar archivos .tar, .tar.gz o .tar.xz.
  • 3. cat: Utilizado en el Makefile para concatenar el archivo comprimido con el script de instalación. Es una utilidad básica presente en todas las distribuciones de Linux.
  • 4. tail: El script del instalador usa tail para leer el contenido del archivo a partir de una línea específica (después del marcador __ARCHIVE__). Esta herramienta viene por defecto en las distribuciones Linux.
  • 5. awk: Se utiliza para buscar la línea que contiene el marcador __ARCHIVE__ y determinar dónde comienza el archivo comprimido en el script. También es una herramienta estándar en los sistemas Unix/Linux.
  • 6. mkdir: Se usa para crear directorios en el sistema de archivos durante el proceso de instalación. Esta herramienta es estándar en cualquier sistema basado en Linux.
  • 7. chmod: Para establecer los permisos adecuados de los archivos instalados (por ejemplo, hacer que el binario sea ejecutable). Es una utilidad estándar de Linux.
  • 8. ln: Utilizado para crear enlaces simbólicos, facilitando el acceso global al binario instalado. También viene preinstalado en los sistemas Linux.

Opcionales (Para Mensajes de Error Visuales):

Si quieres que el script muestre mensajes de error visuales, se pueden utilizar las siguientes herramientas gráficas. Sin embargo, no son estrictamente necesarias y el script seguirá funcionando sin ellas:

  1. zenity (opcional): Utilizado para mostrar mensajes de error gráficos (ventanas emergentes) en entornos de escritorio.
  2. kdialog (opcional):Similar a zenity, utilizado para mostrar mensajes emergentes en entornos KDE.
  3. notify-send (opcional): Utilizado para enviar notificaciones al sistema de notificaciones en entornos de escritorio.
  4. xmessage (opcional): Para mostrar mensajes de error en una ventana de diálogo simple en sistemas X11.

Conclusión

El truco para empaquetar un binario dentro de un script Bash radica en el hecho de que el contenido de un archivo comprimido puede ser parte del mismo script. Siempre que el script Bash pueda diferenciar entre el código de instalación y el contenido binario, puede extraer el archivo y colocarlo en el lugar correcto.

Este tutorial mostró cómo crear un script de instalador completamente auto-contenido en Bash, lo que facilita la distribución y la instalación de tus ejecutables en varios sistemas. Al incrustar el binario o cualquier otro archivo necesario directamente en el script, puedes simplificar el proceso de instalación para los usuarios y garantizar que no se requieran dependencias externas durante la instalación.

Este método es flexible y puede adaptarse a cualquier proyecto, no solo a código compilado. Ya sea que estés distribuyendo scripts, binarios u otros ejecutables, este enfoque te da una forma simple y confiable de crear un instalador portátil.

En resumen:

• Empaquetamos el binario en un archivo comprimido (tarball).
• Lo añadimos al script Bash después de un marcador especial (__ARCHIVE__).
• El script extrae el archivo comprimido y lo instala en el sistema, usando herramientas estándar como awk, tail, y tar.