Hiparco

Recetas y trucos de GNU/Linux e informática en general

Alojado en http://guimi.net

UNetbootin: Crea tus USB/CD de arranque de forma fácil

Existe una herramienta multiplataforma llamada “UNetbootin” que permite de forma muy fácil generar USBs o discos con multitud de sistemas diferentes:
UNetbootin

Tan sencillo como elegir el sistema, elegir el dispositivo y pulsar “Aceptar”.
Se puede elegir entre más de 40 distribuciones preparadas, cada una con varias versiones diferentes disponibles, o seleccionar una ISO que hayamos descargado.

Por supuesto, en Debian es muy sencillo instalar utilizando el sistema habitual:

# aptitude install unetbootin

Conocer la arquitectura de nuestro sistema (32 o 64 bits)

Tenemos varias opciones.

Podemos mostrar información del sistema instalado (toda)

guimi:~$ uname -a
Linux guimi 2.6.32-5-686 #1 SMP Mon Feb 25 01:04:36 UTC 2013 i686 GNU/Linux

O solo el nombre de la arquitectura instalada

guimi:~$ uname -m
i686

En este caso está instalada la arquitectura “i686″ que se utiliza 32 bits. Pero es un modo indirecto de saberlo.

Podemos mirar directamente la configuración del sistema instalado y ver que los bits del sistema:

guimi:~$ getconf LONG_BIT
32

Pero si lo que queremos es conocer la capacidad de nuestro equipo, podemos consultar el micro:

guimi:~$ lscpu
Architecture:          i686
CPU op-mode(s):        32-bit, 64-bit
CPU(s):                2
Thread(s) per core:    1
Core(s) per socket:    2
CPU socket(s):         1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 23
Stepping:              10
CPU MHz:               1999.000
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              6144K 

Ya puestos, podemos consultar toda la información del micro:

guimi:~$ cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 23
model name	: Pentium(R) Dual-Core  CPU      E5200  @ 2.50GHz
stepping	: 6
cpu MHz		: 1203.000
cache size	: 2048 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 2
apicid		: 0
initial apicid	: 0
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 10
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips	: 5000.20
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 23
model name	: Pentium(R) Dual-Core  CPU      E5200  @ 2.50GHz
stepping	: 6
cpu MHz		: 1203.000
cache size	: 2048 KB
physical id	: 0
siblings	: 2
core id		: 1
cpu cores	: 2
apicid		: 1
initial apicid	: 1
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 10
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips	: 5000.05
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

Portadas de libros electrónicos epub

A veces las portadas de los libros electrónicos en formato epub no se cargan correctamente en determinados lectores.
La especificación de epub es un poco vaga y cada lector se fija en una cosa, así que hay epubs que en unos lectores muestran la portada y en otros no.

Los cambios que pongo a continuación pretenden servir para todos los lectores, por lo que para un lector determinado no todos los cambios son necesarios.

IMAGEN DE PORTADA
Cada lector utiliza portadas con diferentes proporciones:
- Una de las más habituales es 3:4 (1,33333), por ejemplo 600×800.
- Otra proporción habitual, utilizada por ejemplo por bq Cervantes light es 1,5: 600×900 – 680×1020
- Otra proporción que he visto utilizada es 1,476: 500×738 – 600×886 – 694×1024

La imagen puede estar en formato JPEG, GIF, PNG, BMP y puede llamarse de cualquier manera, pero por lo de asegurarnos que la acepta el mayor número posible de lectores, la llamaremos “cover.jpg”.

MODIFICACIÓN DE EPUB
Los ficheros epub son en realidad ficheros ZIP con otra extensión.
Para modificar un epub hay que abrir el fichero con cualquier gestor de archivos comprimidos, o descomprimirlo y después volverlo a comprimir.

Buscaremos el archivo “content.opf”, que es el que define el epub. En la misma carpeta ponemos nuestro archivo “cover.jpg” y un fichero nuevo “portada.xhtml”.

El “truco” de portada.xhtml no es necesario en todos los lectores, pero como hemos comentado, no molesta (casi) ponerlo y nos aseguramos una mayor compatibilidad.

CONTENIDO DE portada.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <title>Titulo</title>
    <style type="text/css"> img { max-width: 100%; text-align:center; } </style>
  </head>

  <body>
     <div id="imagen_portada"><img src="cover.jpg" alt="Titulo"/></div>
   </body>

</html>

MODIFICAMOS content.opf

  <metadata ...
  ...
    <meta name="cover" content="imagen_portada"/>
  </metadata>

  <manifest>
  ...
    <item href="cover.jpg" id="imagen_portada" media-type="image/jpg"/>
    <item href="portada.xhtml" id="cover" media-type="application/xhtml+xml"/>
  </manifest>

  <spine toc="ncxtoc">
    <!-- itemref idref="cover" linear="no"/ -->
  ...
  </spine>

  <guide>
    <!-- reference href="cover.jpg" type="cover" title="Cover Image"/ -->
    <reference href="portada.xhtml" type="cover" title="Cover"/>
  </guide>
 

Manejo de cadenas y funciones en scripts bash (bash strign functions)

Dejo aquí un pequeño script con ejemplos de uso de funciones de cadenas y funciones de script.

#!/bin/bash
#
# bash_string_functions.sh
# Por Guimi 2013/01 - http://www.guimi.net
#

# Declaración sin la palabra 'function'
muestra_texto () {
	# Esta asignación no es necesaria
	# La realizo en esta primera función por claridad, en las siguientes trabajaremos con $1
	string_recibida=$1
	echo "La longitud de '$string_recibida' es '${#string_recibida}'"
	echo "A partir del caracter 3 tenemos '${string_recibida:3}'"
	echo "A partir del caracter 3, los siguientes 4 caracteres son '${string_recibida:3:4}'"
}

# Declaración con la palabra 'function'
function muestra_substring () {
	[[ $1 =~ "uno" ]] && echo -n "uno SÍ está en la cadena -- " || echo -n "uno NO está en la cadena -- "
	echo $1
}

# Declaración con la palabra 'function' sin ()
function prueba_substring {
	# Con ${string#substring} recortamos (eliminamos) de string lo que aparece ANTES de LA PRIMERA aparición de substring, empezando por el principio.
	muestra_substring ${1#*.}
	# Con ${string##substring} recortamos (eliminamos) de string lo que aparece ANTES de LA ULTIMA aparición de substring, empezando por el principio.
	muestra_substring ${1##*.}
	# Con ${string%substring} recortamos (eliminamos) de string lo que aparece ANTES de LA PRIMERA aparición de substring, empezando por el final.
	muestra_substring ${1%.*}
	# Con ${string%%substring} recortamos (eliminamos) de string lo que aparece ANTES de LA ULTIMA aparición de substring, empezando por el final.
	muestra_substring ${1%%.*}
}

prueba_reemplazar () {
	# Reemplazamos la PRIMERA aparición de '.' por '#'
	echo ${1/./-}
	# Reemplazamos TODAS las apariciones de '.' por '#'
	echo ${1//./-}
}

datos_script () {
	# Mostramos directorio, nombre y la extensión
	directorio=$(dirname $1)
	nombre_base=$(basename $1)
	extension="${nombre_base##*.}"
	nombre_base="${nombre_base%.*}"
	echo  "$directorio / $nombre_base . $extension"
}

# Función que devuelve un resultado
existe_string_demo () {
	if [ -n "$string_demo" ]
	then
		echo "SÍ"
	else
		echo "NO"
	fi
}

# Generamos una cadena
string_demo="uno.dos.tres.cuatro.cinco"
# Lanzamos las funciones
muestra_texto $string_demo && echo ""
prueba_substring $string_demo && echo ""
prueba_reemplazar $string_demo && echo ""

respuesta=$(existe_string_demo) && echo "La variable string_demo $respuesta existe"
unset string_demo
respuesta=$(existe_string_demo) && echo "La variable string_demo $respuesta existe" && echo ""

# Pasamos el nombre del script ($0) como parámetro
datos_script $0

# Terminamos
exit 0

Prueba de ejecución del script:

La longitud de 'uno.dos.tres.cuatro.cinco' es '25'
A partir del caracter 3 tenemos '.dos.tres.cuatro.cinco'
A partir del caracter 3, los siguientes 4 caracteres son '.dos'

uno NO está en la cadena -- dos.tres.cuatro.cinco
uno NO está en la cadena -- cinco
uno SÍ está en la cadena -- uno.dos.tres.cuatro
uno SÍ está en la cadena -- uno

uno-dos.tres.cuatro.cinco
uno-dos-tres-cuatro-cinco

La variable string_demo SÍ existe
La variable string_demo NO existe

. / bash_string_functions . sh

Modifica metadatos de libros-e

Aquí dejo un script para modificar/consultar los metadatos de una biblioteca de libros-e.
La idea base es que puedo partir de una biblioteca organizada con subdirectorios y modificar/consultar todos los libros-e.
Para casos más sencillo basta con ebook-meta del que este script es tan solo un ‘wrapper’.

#!/bin/bash
#
# libros-e_metadata.sh
# Por Guimi 2013/01 - http://www.guimi.net
#

####################################
# REQUISITOS
# calibre -> ebook-metadata

####################################
#### ERRORES
E_PARAMINVAL=64     # Parametro invalido

####################################
#### AYUDA
muestra_ayuda ()
{
  echo "Use `basename $0` -h para ver la ayuda" >&2
}

muestra_ayuda_larga ()
{
  more << EOF

libros-e_metadata.sh
(c) 2013 Guimi (http://guimi.net)
This software is under the GNU Public License (GPL) v.2

Este script utiliza ebook-meta (calibre) para modificar y mostrar metadatos de ficheros epub de forma recurrente (subdirectorios)

Options:
---------
  -a
  --auto
	Utiliza el nombre del fichero para escribir el autor y titulo del libro en los metadatos
	Presupone el siguiente formato de nombre de archivo: autor-titulo.epub
	Ademas presupone que [autor] es: [1er apellido]_[resto] o [solo una palabra]

	Ejemplos:
		Platon-Escritos_completos.epub
		Sagan_Carl-Cosmos-ed.aniversario.epub

  -h
  --help
    Muestra esta ayuda

  -l
  --limpia
	Borra los metadatos de los campos comentarios, titulo de orden, productor y publicación

  -m [metadatos]
  --metadatos [metadatos]
	Escribe los metadatos dados, utilizando ebook-meta (ver ebook-meta --help)
	La cadena de metadatos debe estar entrecomillada

	Ejemplo:
		libros-e_metadata.sh -m "-l es -c 'Excelente libro'"

  -v
  --verbose
    Muestra todos los metadatos

EOF
}

####################################
# PARAMETROS

# Parámetros por omisión
string_parametros=""

# Comprobacion de parametros
while [ $# -gt 0 ]; do    # Mientras tenemos parámetros...
  case "$1" in
    -a|--auto) # Escribe metadatos a partir del nombre de fichero
      AUTO='0'
      ;;
    -h|--help) # Muestra la ayuda larga
	  muestra_ayuda_larga
      exit 0
      ;;
    -l|--limpia) # Limpia algunos metadatos
	  LIMPIA='0'
      ;;
    -m|--metadatos) # Escribe metadatos
      # Comprobando si hay mas parámetros
      if [ -z "$2" ]
      then
        echo "Error: Falta la cadena de metadatos" >&2
        muestra_ayuda
        exit $E_PARAMINVAL
      else
        string_parametros="$2"
        shift
      fi
      ;;
    -v|--verbose) # Muestra todos los metadatos
      VERBORREICO='0'
      ;;
    -*) # Parametro desconocido
      echo "Error: Parametro desconocido $1" >&2
      muestra_ayuda
      exit $E_PARAMINVAL
      ;;
  esac
  shift # Pasar al siguiente parámetro
done

####################################
# BUCLE PRINCIPAL
# Listamos los ficheros, incluidos subdirectorios
#

# Modificamos el separador de archivos (IFS), por si algun fichero contiene espacios en el nombre
SAVEIFS=$IFS
IFS=$'\n'
# Realizamos el bucle
for x in `find . -type f -iname "*.epub" | sort`
do
	# Limpiamos la cadena de comando del bucle anterior (si lo hubiere)
	string_comando=""

	# COMPROBAMOS SI HEMOS DE ESCRIBIR AUTOR Y TITULO A PARTIR DEL NOMBRE DEL FICHERO
	if [ -n "$AUTO" ]
	then
		# Tomamos los datos del nombre del fichero
		nombre_base=$(basename "$x")
		nombre_base="${nombre_base%.*}"
		libro_autor="${nombre_base%%-*}"
		libro_autor_esp="${libro_autor//_/ }"
		libro_autor_apellido="${libro_autor_esp%% *}"
		libro_autor_resto="${libro_autor_esp#* }"
		libro_autor_largo="$libro_autor_resto $libro_autor_apellido"
		libro_autor_orden="$libro_autor_apellido, $libro_autor_resto"
		libro_titulo="${nombre_base#*-}"
		libro_titulo_esp="${libro_titulo//_/ }"
		#echo  "[$libro_autor_largo] [$libro_autor_orden] [$libro_titulo]"

		# Anotamos los parametros para el conversor
		string_comando="-a '$libro_autor_largo' --author-sort '$libro_autor_orden' -t '$libro_titulo_esp' --title-sort ''"
	fi

	# COMPROBAMOS SI HEMOS DE LIMPIAR METADATOS
	if [ -n "$LIMPIA" ]
	then
		# Anotamos los parametros para el conversor
		string_comando=$string_comando" -c '' -p '' -k '' -d '' --title-sort ''"
	fi

	# COMPONEMOS LA ORDEN E INDICAMOS POR QUÉ FICHERO VAMOS
	if [ -n "$VERBORREICO" ]
	then
		comando="ebook-meta $string_comando $string_parametros '$x'"
		echo  "----------- $x ----------"
	else
		if [ "$string_comando" == "" ] && [ "$string_parametros" == "" ]
		then
			comando="ebook-meta '$x' | grep -e Title -e Author -e Language"
			echo  "----------- $x ----------"
		else
			comando="ebook-meta $string_comando $string_parametros '$x' > /dev/null"
			echo  "$x ..."
		fi
	fi

	# LANZAMOS EL CONVERTIDOR
	eval $comando

done
# Restauramos el separador de archivos (IFS)
IFS=$SAVEIFS

####################################
# Terminamos
exit 0

Convierte libros-e

Aquí dejo un script para convertir una biblioteca de libros-e al formato epub (o al que se quiera).
La idea base es que puedo partir de una biblioteca organizada con subdirectorios y convertir todos los libros-e al formato deseado sin alterar la estructura y guardando copia de los originales en una estructura nueva copiada de la antigua.
Para casos más sencillo basta con ebook-convert del que este script es tan solo un ‘wrapper’.

#!/bin/bash
#
# libros-e_convierte.sh
# Por Guimi 2013/01 - http://www.guimi.net
#

############
# REQUISITOS
# calibre -> ebook-convert

# Extensiones a convertir
#extensiones="pdf epub txt png jpg jpeg bmp doc docx djvu"
extensiones="rtf lit fb2 mobi"

# Contadores estadísticos
contador_total=0
contador_ok=0
contador_no=0

# Tomamos el directorio inicial, ya que trabajaremos con subdirectorios
directorio_base=$(pwd)

# Generamos un directorio donde guardar los originales.
# Este directorio está fuera de nuestra ruta, así podemos ejecutar repetidas veces el script sin volver a convertir los archivos
mkdir ../originales

# Listamos los ficheros, incluidos subdirectorios
for x in `find . -type f | sort`
do
	# Incrementamos contador estadístico
	let contador_total=contador_total+1

	# Primero hemos de tomar el directorio, el nombre y la extensión
	directorio=$(dirname "$x")
	nombre_base=$(basename "$x")
	extension="${nombre_base##*.}"
	nombre_base="${nombre_base%.*}"
	#echo "$directorio | $nombre_base | $extension"

	# Comprobamos si la extensión del fichero es una de las buscadas
	[[ $extensiones =~ $extension ]] && reconocido=0 || reconocido=1
	# Convertimos el fichero
	if [ $reconocido -eq 0 ]
	then
		echo  -n "Convirtiendo $x..."
		# Cambiamos al directorio del fichero, si no ebook-convert no trabaja bien (!?)
		cd $directorio
		# Hacemos una conversión silenciosa y tomamos la salida (ejecución terminada con éxito o con error)
		ebook-convert $nombre_base.$extension $nombre_base.epub > /dev/null 2> /dev/null
      	SALIDA=$?
		# Volvemos al directorio de trabajo
		cd $directorio_base

		# Comprobamos si la conversión ha sido exitosa
      	if [ "$SALIDA" -gt 0 ]
      	then
			# Incrementamos contador estadístico
			let contador_no=contador_no+1
			echo " ERROR!!!"
		else
			# Incrementamos contador estadístico
			let contador_ok=contador_ok+1
			echo " ok"
			# Generamos el mismo arbol de directorios para lo originales y movemos el archivo
			mkdir ../originales/$directorio -p 2> /dev/null
			mv $directorio/$nombre_base.$extension ../originales/$directorio/$nombre_base.$extension
      	fi
	fi
done

# Mostramos unas pequeñas estadísticas
echo ""
echo "Total ficheros: $contador_total | Convertidos: $contador_ok | Con error: $contador_no"

# Terminamos
exit 0

Conversión juego de caracteres UFT-8, ISO…

Convertir el nombre de los ficheros (paquete convmv):

$ convmv -f iso-8859-15 -t UTF-8 -r * –notest

Convertir el contenido de un fichero:

$ iconv fichero.in -f iso-8859-15 -t utf-8 -o fichero.out

Poner saltos de línea estilos Unix o estilo DOS (paquete tofrodos):

$ unix2dos fichero.in
$ dos2unix fichero.in
unix, dos, charset, juego de caracteres, utf

Background / Foreground jobs – gestión de trabajos en fondo

Para pasar un trabajo al fondo (background) podemos pulsar Ctrl+z durante su ejecución y detenerlo:

$ sleep 10
^Z
[1]+  Detenido                sleep 10

También podemos ejecutarlo directamente en background con “&”:

$ sleep 10 &
[1] 5166

Otra opción es ejecutarlo modificando su prioridad con “nice” y “renice”:

$ nice
0
$ nice sleep 10 &
$ nice -n 5 ls
# nice -n -2 ls
$ renice +1 [PID]

Para ver el listado de trabajos en background:

$ jobs
[1]+  Detenido                sleep 10
[2]-  Ejecutando              sleep 10 &

Atención Como se ve, no es lo mismo detenerlo y dejarlo en background, que ejecutarlo en background.

Siguiendo el ejemplo, pasados 10 segundos, cuando ejecutemos cualquier comando, o pulsando intro nos dice:

$
[2]-  Hecho                   sleep 10

Pero el primero sigue en espera:

$ jobs
[1]+  Detenido                sleep 10

Podemos matarlo y terminarlo con:

$ kill %1
[1]+  Terminado               sleep 10

O podemos recuperarlo con:

$ fg %1
sleep 10