Crear un instalador auto-extraible para GNU/Linux

Hay que facilitar la vida al usuario; y nada mejor que hacer un instalador sencillito donde todo está empaquetado en un .sh... pero ¿cómo se hace?

No he encontrado mucha información al respecto y, aunque no es complicado, puede que no se te ocurra directamente cómo hacerlo.

Bien, pues simplemente hay que utilizar la estupenda herramienta cat y añadir el binario a descomprimir al final del fichero de shell... Como muestra un botón. Eye-wink

$ cat cabeceraInstalador.sh todocomprimido.tgz > instalador.sh

Bien, con la orden anterior concatenamos el fichero que tendrá las órdenes a realizar del shell (cabeceraInstalador.sh), con el binario comprimido (todocomprimido.tgz), y lo juntamos en el fichero final llamado instalador.sh. ¿Cómo decirle al script dónde empieza la parte binaria del archivo? Utilizando la bonita utilidad tail.

#!/bin/sh
echo ""
echo "AutoInstalador del programa XX.XX v.1.0"
echo ""

# Cogemos la parte de este archivo a partir de la lí­nea 11 y
# se la mandamos al tar para que la descomprima.
tail -n +11 $0 | tar xvz

exit 0

En el caso anterior, le pasamos a tail el parámetro +11, porque el fichero del script tiene 10 lí­neas. Podemos automatizar la tarea de contar el número de lí­neas haciendo un script un poco más complejo que, además utiliza un directorio temporal y ejecuta un script de instalación (que estará dentro del .tgz). Veamos el script en versión "pro":

#!/bin/sh
echo ""
echo "AutoInstalador del programa XX.XX v.1.0"
echo ""

# Creamos un directorio temporal donde lo extraeremos
export WRKDIR=`mktemp -d /tmp/selfextract.XXXXXX`

# Contamos las lineas de este fichero con awk. La cadena
# "__AQUI_SIGUE_EL_BINARIO__" debe ser la ultima linea del
# script. Le sumamos una a la ultima linea y la guardamos
# en SKIP.
SKIP=`awk '/^__AQUI_SIGUE_EL_BINARIO__/ { print NR + 1; exit 0; }' $0`

# Cogemos la parte de este archivo a partir de la lí­nea 11 y
# se la mandamos al tar para que la descomprima en el temporal.
tail -n +$SKIP $0 | tar xvz -C $WRKDIR

# Nos vamos al temporal y ejecutamos el script de instalacion
PREV=`pwd`
cd $WRKDIR
./install.sh

# Borramos los ficheros temporales
cd $PREV
rm -rf $WRKDIR

exit 0

__AQUI_SIGUE_EL_BINARIO__

Pues nada más. Seguiré mirando la forma de crear buenos instaladores. Desde luego, el script anterior es muy pobre. Se puede mejorar añadiendo un bonito interfaz en modo texto con dialog o sus equivalentes en modo gráfico gdialog y kdialog aunque no se... me sigue gustando más la de modo texto; además es más estándar y como dirí­a Neal Stephenson, "En el principio fue la lí­nea de comandos".

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Error generado

He intentado realizar el codigo que de ante mano me esta estipulado y me ha dado el siguiente error:

sh install.sh

AutoInstalador del programa XX.XX v.1.0

gzip: stdin is encrypted -- not supported
tar: Child returned status 1
tar: Error exit delayed from previous errors

que estara mal?

Perfecto, funciona bastante

Perfecto, funciona bastante bien , y la verdad es que es correcto,..........ni hay mucha informacion al respecto, ni jamas se me hubiera ocurrido como logralo (aunque lo estube maquinando).

saludos.

una pequeña correccion

Me parece muy bueno lo que expones, sin embargo lo probe y hay un pequeño problema.
Hay un error que dice que la forma como usted utiliza la utilidad tail esta deprecada:

lo unico que hay que hacer es cambiar esta linea:

tail +$SKIP $0 | tar xvz -C $WRKDIR

por esta otra:

tail -n +$SKIP $0 | tar xvz -C $WRKDIR

o sea solo agregar el parametro -n.