#! /bin/sh # Script que hace de interfaz para ver el contenido de un fichero .gz, # incluyendo extensiones para los ficheros .tar.gz # ATENCIÓN: Este script da por sentado que si hay un solo fichero ¡NO # se está utilizando el tar! BASEDIR=~/cambio TMPDIR=/tmp/gzv$$ LISTA=/tmp/gzvlista$$ # Definimos tres variables que contienen datos importantes del programa. # El primero es donde por defecto extraeremos los ficheros, # y el segundo el directorio temporal donde extraeremos temporalmente el # contenido del gzip. Para que sea único, utilizamos el PID del proceso # El tercero es el fichero donde pondremos un listado de los ficheros # contenidos en el .gz VERSION=1.1b GZIPFLAGS="-9" # Dos variables para hacer mas legible y modificable el codigo : ${EDITOR:=/bin/vi} # Si la variable EDITOR no tiene nada, por defecto utilizamos el vi # para editar los ficheros de texto nombreprograma=`basename "$0"` nomfich=`basename "$1"` # Guardamos en dos variables el nombre del programa que se esta llamando # (que deberia ser gzview), y en otra el nombre sin directorios del fichero # que se esta intentando ver MENSAJE="[#] - editar archivo con ese numero d - descomprimir q - salir de $nombreprograma l - listar archivos" # Definimos una funcion que actualiza el fichero .gz actualizar() { if [ `ls -l $TMPDIR | wc -l` -gt 2 ]; then # Si el numero de ficheros es mayor que uno, preparamos primero el tar pushd $TMPDIR &>/dev/null tar cf $nombrecontar * popd &>/dev/null gzip $GZIPFLAGS $TMPDIR/$nombrecontar else # Si solo hay un fichero, lo comprimimos con gzip nombrecontar=`ls $TMPDIR` gzip $GZIPFLAGS "$TMPDIR/$nombrecontar" fi cp "$TMPDIR/$nombrecontar.gz" "$1" } trap 'rm -rf $TMPDIR $LISTA' 1 2 15 if [ "$#" -ne 1 ]; then echo "$nombreprograma $VERSION (c) Esteban Manchado 'ZoSo'" echo "$nombreprograma: ERROR: Se necesita un solo parametro" echo "$nombreprograma: SINTAXIS: $nombreprograma " exit -1 fi # Ahora sabemos que tenemos un solo parametro. Este es el nombre del fichero, # asi que lo descomprimimos en el directorio $TMPDIR, despues de chequear # si vamos a tener problemas con el o no if [ ! -f "$1" ]; then echo "$nombreprograma: $1: No existe o no es un fichero valido" exit -1 fi mkdir $TMPDIR cp "$1" $TMPDIR if ! gunzip "$TMPDIR/$nomfich"; then echo "$nombreprograma: gunzip devolvio un error. Abortando..." exit -1 fi # Ahora tenemos que comprobar si los cuatro ultimos caracteres del nombre # del fichero, guardado en $nomfich, son '.tar'. Si es asi, entonces # procederemos a intentar desempaquetarlo, en el directorio $TARDIR # Hagamos lo que hagamos, tenemos que presentar la lista de los ficheros # al usuario en pantalla, para que elija lo que quiere hacer con ellos # (editarlos, actualizarlos, descomprimirlos en el directorio $BASEDIR...) # Miramos si el fichero tiene extension .tar. Para ello, lo que haremos sera # comprobar si el nombre y el nombre sin extension .tar son iguales. Ambos # los hallamos con basename nombrecontar=`basename $TMPDIR/*` nombresintar=`basename $TMPDIR/* \.tar` if [ "$nombrecontar" != "$nombresintar" ]; then # Entonces el nombre tiene extension '.tar', asi que lo descomprimimos en # un directorio y ense~amos la lista al usuario nombresintar=`ls $TMPDIR` # Tiene que salir el nombre de un solo fichero, porque la compresion # .gz solo permite comprimir un archivo pushd "$TMPDIR" &>/dev/null tar xf "$TMPDIR/$nombresintar" tar tf "$TMPDIR/$nombresintar" >$LISTA # Tenemos la lista de los ficheros en el fichero $LISTA grep -v "\/\$" $LISTA >$TMPDIR/$$ mv $TMPDIR/$$ $LISTA # Borramos los directorios, que seran lineas terminadas en '/' popd &>/dev/null # Cambiamos el directorio temporalmente, porque el tar siempre # desempaqueta en el directorio actual, y luego volvemos al directorio # donde estuvieramos rm "$TMPDIR/$nombresintar" else # Entonces el fichero no tiene extensión .tar, así que debe ser un fichero # directamente comprimido con el gzip. Lo enseñamos con $EDITOR y comprobamos # si ha cambiado, para preguntar al usuario si quiere actualizarlo. Entonces, # pase lo que pase, salimos del script fichero=`ls "$TMPDIR"` fichero=`basename $fichero` echo $fichero >$LISTA # Ponemos el nombre del fichero descomprimido del .gz en el fichero $LISTA echo "Editando $fichero..." orden="ls -l --full-time $TMPDIR/$fichero | awk '{ print \$7\$8\$9 }'" eval fecha=\`$orden\` # Salvamos la fecha inicial en una variable sleep 1 # Esperamos un rato, para que el usuario vea el mensaje # Asi tambien nos aseguramos de que ha pasado al menos un segundo $EDITOR $TMPDIR/$fichero eval fechanueva=\`$orden\` if [ "$fecha" != "$fechanueva" ]; then # La fecha ha cambiado, preguntamos por actualizar el fichero .gz echo echo "El fichero $fichero ha cambiado ?Desea salvar los cambios? [s/N]" read tecla if [ "$tecla" = "s" ]; then actualizar $1 else gzip -dc "$1" >$TMPDIR/$fichero fi fi # Borramos los directorios temporales y salimos rm -rf $TMPDIR $LISTA exit fi # Ahora, tenemos la lista de los ficheros que hemos de presentar al usuario # en el directorio $TMPDIR, asi que hacemos la lista y la presentamos cat -n $LISTA numfich=`cat $LISTA | wc -l` until [ "$tecla" = "q" ] do echo "$MENSAJE" read tecla # Lo de 2> es para que no de error de que $tecla no es entero, cuando # el usuario pulse una letra o algo asi if [ "$tecla" -gt "$numfich" ] 2>/dev/null; then echo "Pulse un numero menor o igual que $numfich, 'r' para" echo "responder a algun mensaje o 'q' para salir" continue # Saltamos a la siguiente iteracion fi if [ "$tecla" -le "$numfich" ] 2>/dev/null; then orden="awk 'BEGIN { contador=1; indice=ARGV[2]; ARGC=2 } { if (contador == indice) { print; exit } else contador++ }' $LISTA $tecla" # Hallamos el fichero que va en la posicion que indica $tecla eval fichero=\`$orden\` echo "Editando $fichero..." orden="ls -l --full-time $TMPDIR/$fichero | awk '{ print \$7\$8\$9 }'" eval fecha=\`$orden\` # Salvamos la fecha inicial en una variable sleep 1 # Esperamos un rato, para que el usuario vea el mensaje # Asi tambien nos aseguramos de que ha pasado al menos un segundo $EDITOR $TMPDIR/$fichero eval fechanueva=\`$orden\` if [ "$fecha" != "$fechanueva" ]; then # La fecha ha cambiado, preguntamos por actualizar el fichero .gz echo echo "El fichero $fichero ha cambiado ?Desea salvar los cambios? [s/N]" read tecla if [ "$tecla" = "s" ]; then actualizar $1 else # Tenemos que recuperar el fichero original. La opcion -O del # tar es para que saque el fichero por la salida estandar, porque # si no hay problemas con los subdirectorios if [ `ls -l $TMPDIR | wc -l` -gt 2 ]; then # Si hay mas de un fichero hay un tar gzip -dc "$1" | tar xO "$fichero" >$TMPDIR/$fichero else gzip -dc "$1" >$TMPDIR/$fichero fi fi fi fi case "$tecla" in l) # Opcion de listar los archivos de nuevo if [ ! -f $LISTA ]; then # Si ha pasado algo con el fichero temporal, lo creamos de nuevo ls $TMPDIR >$LISTA numfich=`cat $LISTA | wc -l` fi cat -n $LISTA | more;; d) # Opcion de descomprimir en un directorio determinado echo "Introduzca el numero del fichero que quiere descomprimir" read tecla if [ "$tecla" -gt $numfich ] &>/dev/null; then echo "Numero de fichero invalido" break # Salimos del case fi orden="awk 'BEGIN { contador=1; indice=ARGV[2]; ARGC=2 } { if (contador == indice) { print; exit } else contador++ }' $LISTA $tecla" # Hallamos el fichero que va en la posicion que indica $tecla eval fichero=\`$orden\` if cp $TMPDIR/$fichero $BASEDIR; then echo "Fichero copiado en $BASEDIR" else echo "Error al copiar fichero $fichero en el directorio $BASEDIR" fi;; # Editamos el fichero que esta en la posicion que dice la # variable $tecla. Mediante el awk conseguimos el nombre # del fichero esac done # echo "?Quiere borrar los ficheros?" # read tecla # if [ "$tecla" != "n" ]; then rm -rf $TMPDIR $LISTA # fi # Borramos el directorio que hemos creado, recursivamente