jueves, 29 de octubre de 2015

Calcular resumen criptográfico MD5, SHA1 y SHA256 en Windows

Recientemente tuve la necesidad de comprobar la integridad de una descarga en Windows. Usualmente, cuando son descargas grandes, utilizo Firefox con el complemento DownThemAll, el cual permite agregar el valor del resumen criptográfico para validar el archivo. Pero como ya el archivo estaba descargado, decidí buscar una solución para este caso.

Luego de buscar en Internet, conseguí una herramienta de Microsoft que cumple esta función. Se trata de File Checksum Integrity Verifier (FCIV).

  1. Descargué el archivo ZIP desde la página y lo descomprimí.
  2. Creé una carpeta FCIV en Archivos de Programa (Como administrador en la consola de comandos):
  3. mkdir %PROGRAMFILES%\FCIV
  4. Luego, moví el contenido del archivo ZIP a la carpeta recién creada
  5. Finalmente, añadí el directorio creado a la variable de ambiente PATH
  6. setx PATH "%PATH%;%PROGRAMFILES%\FCIV"
Para utilizar la herramienta, sólo hay que ejecutar en la consola
fciv archivo
Para conocer las opciones
fciv /? 

jueves, 10 de septiembre de 2015

Desinstalar actualizaciones de Windows por consola de comandos

Estaba leyendo sobre varias actualizaciones indeseables de Windows, y decidí validar que no estuviesen instaladas en mi sistema, para lo cual fui a la sección de Actualizaciones de Windows en el Panel de Control.

Sin embargo, me resultó engorroso consultar puntualmente si las actualizaciones de mi interés estaban instaladas o no.

Buscando en Internet, conseguí que el comando para listar todas las actualizaciones instaladas es:
wmic qfe list
Podemos filtrarlo utilizando
wmic qfe list | findstr KB1234567
Podemos redireccionar la salida del comando a un archivo de texto, y ahí consultar más cómodamente con
wmic qfe list > C:\kblist.txt
cat C:\kblist.txt | findstr KB1234567
Para desinstalar una actualización, basta con ejecutar
wusa /uninstall /kb:1234567 /quiet /norestart 

viernes, 4 de septiembre de 2015

Instalación sencilla de Sysinternals

Viniendo de Linux, me resultó particularmente frustrante que al intentar ejecutar el comando "whois" en la consola de comandos de Windows, me indicase que no existía ese ejecutable en mi equipo.

Una rápida búsqueda en Google me lleva a la página de Microsoft de Sysinternals, y allí veo que tengo la opción de descargar "whois" individualmente, o la suite completa. Para no pasar otra vez por una molestia similar, decidí descargar la suite.

Pensé que el archivo ZIP iba a tener algunas indicaciones, o por lo menos recomendaciones, para instalarlos, pero no fue el caso. Es un archivo ZIP que contiene un montón de ejecutables, un archivo LEEME, acuerdos de usuario final, y algunos archivos de ayuda para las aplicaciones.

Otra búsqueda en Google, me lleva a varios instaladores desarrollados por terceros -lo cual no me inspira mucha confianza- y algunos guiones de comandos en algunos foros para crear accesos directos en el menú inicio -lo cual no me interesa.

Finalmente, decidí abrir CMD como administrador, ejecutar el comando
mkdir "C:\Program Files\Sysinternals"
Copiar el contenido descomprimido del archivo zip dentro de esa carpeta, y luego agregarla a PATH, para que sea ejecutable desde la consola sin tener que indicar la ruta completa del ejecutable. Para eso ejecuté:
setx PATH "%PATH%;C:\Program Files\Sysinternals"
Listo. Ahora puedo ingresar whois ejemplo.com desde la consola. La primera vez que se ejecuta pide aceptar un acuerdo de usuario final.

viernes, 7 de agosto de 2015

Error con la JRE al editar Macros en Libreoffice Basic

Estaba intentando automatizar un patrón particular de búsqueda y reemplazo en unos documentos, buen Windows, y se me ocurrió que una forma de realizarlo sería utilizando Macros de Libreoffice.
Primero tuve que habilitar la ejecución de Macros, para lo cual Libreoffice me solicitó que especificase un ambiente de ejecución de Java (JRE). Sin embargo, Libreoffice me indicó que el JRE seleccionado estaba defectuoso o no era compatible.
Luego de buscar en Internet, encontré que este error se presenta si Libreoffice està compilado para 32 bits y la JRE especificada es de 64 bits. La versión de Libreoffice para Windows está compilada para 32 bits.
El problema se solucionó al instalar una versión de la JRE de 32 bits y configurar Libreoffice para que la utilizase.

lunes, 16 de febrero de 2015

Modificar los menúes en Gnome Classic

Como antiguo usuario de Gnome2, prefiero utilizar Gnome Classic (antiguamente llamado Fallback) que Gnome3 o Unity. De la misma forma, es la opción de escritorio que dejo a mis padres, quienes ya aprendieron a utilizar Linux con Gnome2, y Gnome Classic les permite utilizarla sin tener que recibir un nuevo entrenamiento.
En estos días se presentó un problema en el panel inferior con la barra de tareas, la cual dejó de mostrar las aplicaciones abiertas para poder alternar entre una y otra, teniendo que recurrir a la combinaciòn de taclas Alt + Tab para cambiar entre ventanas.
En Gnome2, esto se abría resuelto haciendo clic secundario en el panel, y agregando algún elemento (widget) o icono. Luego de un par de búsquedas en Google, pude averiguar que en Gnome Classic sencillamente hay que pisar la tecla Alt y luego hacer el clic secundario en el panel. Después de esto el procedimiento es muy similar, incluso idéntico, al de Gnome 2.

viernes, 26 de diciembre de 2014

Aplicando unzip masivo a archivos con espacios

Tenía una carpeta llena de archivos ZIP, cuyos nombres contenían espacios, paréntesis, apóstrofes y otros caracteres especiales.
Carpeta
+ Primer Archivo.zip
+ Archivo (Paréntesis).zip
+ Archivo 'Apóstrofe.zip
Y mi intención era descomprimirlos todos de una sola vez, para que otra aplicación importase los archivos internos, manteniendo la jerarquía de carpetas.
Mi primer intento fue
unzip *.zip
Error. Unzip tomaba cada fragmento separado por espacio como un parámetro individual.
Luego vino
find *.zip -type f -exec unzip {} \;
Error. Unzip seguía tomando cada fragmento separado por espacio como un parámetro individual.
Entonces intente con un null como separador, no conseguí el comando de unzip que le permitiese entender el separador null, así que incorporé xargs al comando, incluso intenté con comillas.
find *.zip -type f -print0 | xargs -0 unzip {}
find *.zip -type f -print0 | xargs -0 unzip "{}"
Mismo error.
Descubrí que ls -b da como salida una lista de nombres de archivo con los espacios escapados.
ls -b *.zip | xargs unzip {}
Mismo error. Probé con echo, y sospecho que xargs se come las escapadas de los espacios.
Empiezo el camino de admisión de derrota al redactar un pequeño guión bash
#!/bin/sh

for file $(ls -b *.zip)
do
    unzip $file
done
Mismo error. Resulta que el for toma cada pedazo separado por espacios.
Quedaban dos opciones de admisión total de derrota ante el reto de descomprimir masivamente archivos ZIP con espacios en el nombre:
  1. Eliminar los espacios de los nombres de archivo
  2. Lanzar muchos comandos de descompresión
Me fui por la segunda opción. No era una aceptable escribir cada comando manualmente, así que construí un comando que elaborase un guión bash especializado.
echo "#!/bin/sh" > descomprimir.sh
ls -b *.zip | sed 's/^/unzip /' >> descomprimir.sh
chmod +x descomprimir.sh
./descomprimir.sh
El archivo resultante, descomprimir.sh queda de la forma:
#!/bin/sh
unzip Primer\ Archivo.zip
unzip Archivo\ (Paréntesis).zip
unzip Archivo\ 'Apóstrofe.zip
Eso hizo 90% del trabajo. Me di cuenta de que los paréntesis y los apóstrofes seguían dando problemas. Como ya había descomprimido parte de los archivos, decidí generar el archivo anterior nuevamente de forma que unzip no reescribiese los archivos ya extraídos, lo cual se logró con unzip -n. Escapar el apóstrofe requirió utilizar el valor en hexadecimal.
echo "#!/bin/sh" > descomprimir.sh
ls -b *.zip | sed 's/^/unzip -n /' |\
sed 's/(/\\(/' | \sed 's/)/\\)/' | sed "s|\x27|\x5c\'|">> descomprimir.sh
chmod +x descomprimir.sh
./descomprimir.sh
Con esto, el archivo quedó de la forma
#!/bin/sh
unzip -n Primer\ Archivo.zip
unzip -n Archivo\ \(Paréntesis\).zip
unzip -n Archivo\ \'Apóstrofe.zip
Éxito. Se descomprimieron todos los archivos.
Como reflexión final, quizás hubiese sido más sencillo renombrar masivamente los archivos para eliminar los espacios, o quizás los paréntesis y los apóstrofes igual me hubiesen llevado por el mismo camino. Otro día investigaré más a fondo las posibilidades de xargs o algún otro comando de escapar todos los caracteres especiales.

sábado, 25 de octubre de 2014

Desduplicar archivos idénticos en Linux

Recientemente tuve que reconstruir mi colección de música a partir de mi reproductor varios respaldos parciales (en un reproductor de música, en una memoria USB, una computadora vieja, etc), y aparte del problema de tener que categorizar de nuevo algunas canciones, me encontré con que un mismo archivo estaba en diferentes carpetas o rutas en los diversos soportes, por lo cual colocar todas las subcarpetas en un mismo directorio resultaba en un que una misma canción podía estar repetida varias veces.

Inicialmente, quise utilizar los metadatos de las canciones para detectar los archivos duplicados, pero era un trabajo manual muy tedioso ordenar por artista e ir leyendo cada una, así que decidí hacer un guión en bash.

A continuación el método a grandes rasgos:
  1. Para detectar si un archivo está repetido, se hará una comparación de su huella SHA256, una función robusta de resumen criptográfico.
  2. Se comparan dos carpetas a la vez (en mi caso una carpeta con una colección parcial que estaba mejor estructurada que otra carpeta con canciones sueltas).
  3. Se ejecuta la función de SHA256 sobre todos los archivos de una carpeta y se almacena el nombre y la huella de cada archivo. Luego se ejecuta la operación con la otra carpeta.
  4. Se combinan ambos listados y para determinar si alguna huella está repetida.
  5. Para los casos cuando un archivo esté duplicado, en una carpeta se conservará y en la otra será eliminado. Por simplicidad, en una carpeta siempre se conservará y en la otra siempre se eliminará.
  6. Se utiliza la información de las huellas repetidas para determinar a cuales archivos se corresponden en la carpeta para eliminar.
  7. Se borran masivamente los archivos repetidos en la carpeta para borrar.
El guión quedó así:
#!/bin/sh

# Autor: J. Navarro
# Fecha: 2014
# Este programa se distribuye bajo licencia GPLv2
# Puede obtener el texto completo de la licencia en:
# http://www.gnu.org/licenses/gpl-2.0.html


#Inicialización de variables

NOBORRARDIR=<carpeta donde se conservan los duplicados>;
NOBORRARTMP="/tmp/noborrar.sha256";
NOBORRARREP="/tmp/noborrar.sha256.repetido";

BORRABLEDIR=<carpeta de donde se eliminan los duplicados>;
BORRABLETMP="/tmp/borrable.sha256";
BORRABLEREP="/tmp/borrable.sha256.repetido"

REPETIDOTMP="/tmp/repetido.sha256"
REPETIDOMIX="/tmp/repetido-mix.sha256"

#Ejecución de comandos

echo "Generando resumen criptografico de $NOBORRARDIR"

find $NOBORRARDIR -type f -exec sha256sum {} + > $NOBORRARTMP

echo "Generando resumen criptografico de $BORRABLEDIR"

find $BORRABLEDIR -type f -exec sha256sum {} + > $BORRABLETMP

echo "Detectando archivos repetidos"

 #listado de resumenes criptograficos de archivos repetidos
cat $NOBORRARTMP $BORRABLETMP | cut -f1 -d\ | sort | uniq -d \
> $REPETIDOTMP


#listado combinado donde los archivos repetidos estan juntos
cat $NOBORRARTMP $BORRABLETMP | sort | egrep -f $REPETIDOTMP \
> $REPETIDOMIX

# Cuando grep genera el error "Referencia hacia atrás inválida"
# cat $NOBORRARTMP $BORRABLETMP | grep -F -f $REPETIDOTMP | sort \

#> $REPETIDOMIX

#visualizar el listado de archivos repetidos
pager $REPETIDOMIX

echo "Archivos repetidos a conservar"

egrep $NOBORRARTMP -f $REPETIDOTMP > $NOBORRARREP
pager $NOBORRARREP

echo "Archivos repetidos a eliminar"

egrep $BORRABLETMP -f $REPETIDOTMP > $BORRABLEREP
pager $BORRABLEREP

# Se toman solamente los nombres de archivo,
# se encierran entre comillas y se borran.
cat /tmp/borrable.sha256.repetido | perl -pe "s/[^ ]+[ ]+//" | \
perl -pe 'chomp $_; $_="\"$_\"\n"' | xargs rm