jueves, 26 de marzo de 2009

Comandos : Pipe Viewer ... ¿Qué está pasando por esta tubería?

A medida que voy conociendo más acerca de los sistemas Unix me van llamando la atención diferentes comandos. Hoy comienzo a examinar el comando pv, pero en lo sucesivo trataré de abordar otros que son de obligatoria referencia para cualquier persona que se proponga dominar y aprovechar al máximo las posibiliades que ofrece la consola del sistema operativo GNU/Linux. Y en todo el proceso iremos viendo ejemplos prácticos, varias veces con videos demostrativos incluídos.

Por su parte, el nombre del comando pv se deriva del acrónimo del término Pipe Viewer. Esta es la herramienta que permite monitorear el progreso del flujo de datos a través de una tubería o pipe. Por tanto, podemos insertarlo entre dos procesos para obtener una indicación visual sobre la velocidad de la transferencia de datos, el tiempo que tarda la misma y el estimado para que concluya. ¿Cómo se usa? Siga leyendo ... Y no lo dude ... simelo pide abordaré la utilización del comando que Ud me sugiera. Si tiene dudas o cualquier sugerencia ... espero sus comentarios. Si está interesado en saber más acerca de este tema, le invito a suscribirse a esta serie ... y si desea estar más informado, también puede suscribirse usando RSS a todas las entradas de este blog ... y más recientemente también puede recibir todos los artículos por correo nuevo.

¿Cómo se usa pv?

El comando ha sido escrito por Andrew Wood, un sysadmin de Unix experimentado. En su sitio oficial podemos conocer algunos detalles de interés. Pero más allá de esta descripción, pasemos a ver algunos ejemplos de su uso, comenzando por lo más simple hasta llegar a los más sofisticados y, por tanto, complejos.

Supongamos que tenemos un fichero (por ejemplo trac.log) que contiene unos cuántos gigabytes. Para aprovechar el espacio de su servidor se decide comprimirlo y archivarlo en un momento dado. Normalmente esto se haría más o menos así ...

$ gzip -c myfile.bin > myfile.bin.gz

Pero como el fichero es inmenso (varios gigabytes), no se tiene referencia acerca de los tiempos que va tomando esta actividad. ¿Terminaremos pronto? ¿Habrá que esperar otros 30 minutos? Utilizando pv se pueden conocer estos detalles. La manera más simple de hacerlo es así ...

$ pv myfile.bin |gzip > myfile.bin.gz
611MB 0:00:11 [58.3MB/s] [=>      ] 15% ETA 0:00:59

En este caso pv actúa como cat, pero además añade una barra de progreso. En este momento en particular podemos ver cómo gzip ha procesado 611MB de datos en 11 segundos. Esto representa el 15% del total a procesar y se estima que el proceso concluya después de otros 59 segundos. En general se pueden intercalar múltiples instancias de pv. Un ejemplo práctico podría ilustrar el uso de pv para tener una idea, en tiempo real, de la tasa apróximada de compresión. Para esto se podría considerar el monitoreo de la lectura y la escritura realizada por el comndo gzip.

$ pv -cN source myfile.bin | gzip | pv -cN gzip > myfile.bin.gz
source:  760MB 0:00:15 [37.4MB/s] [=>     ] 19% ETA 0:01:02
gzip: 34.5MB 0:00:15 [1.74MB/s] [  <=>  ]

En este último caso se ha especificado el parámetro -N para identifica la tubería con un nombre. El parámetro -c asegura que la salida del primer comando pv no interfiera al segundo proceso pv mientras contabiliza los datos de salida. A los efectos de este ejemplo, el fichero trac.log se lee a una velocidad de 37.4MB/s pero gzip va entregando datos solamente a 1.74MB/s. Por tanto la tasa de compresión viene siendo de apróximadamente 37.4/1.74 = 21x! Preste también atención a que pv no muestra cuántos datos quedan por procesar y no estima la duación del proceso, debido a que no tiene la menor idea acerca del tamaño del fichero comprimido. El primer comando sí posee esta información puesto lee directamente desde el fichero.

Otro ejemplo similar sería empaquetar un directorio en un archivo tarball:

$ tar -czf - . | pv > ../myfile.bin.gz
117MB 0:00:55 [2.7MB/s] [>         ]

En este caso pv solo muestra la tasa de transferencia a la salida del comando tar -czf. Realmente esto se podría haber hecho de otra manera más efectiva. Por ejemplo, de esta manera no se sabe cuánto falta por procesar. Para ello se necesita suministrar explícitamente la cantidad de bytes que ocupan el directorio y los ficheros que este contiene. Esto se hace así ...

$ tar -cf - . | pv -s $(du -sb . | awk '{print $1}') | gzip > ../myfile.bin.gz
253MB 0:00:05 [46.7MB/s] [>     ]  1% ETA 0:04:49

Lo que sucede en este caso es que le decimos a tar que cree -c un archivo cnon todos los ficheros en el directorio actual . (recursivamente) y que envíe los resultados hacia la salida estándar -f -. Luego le especificamos a pv el tamaño -s de todos los ficheros en el directorio. Para esto nos auxiliamos del comando intermedio du -sb . | awk ’{print $1}’, y así se logra que dicho número de bytes sea suministrado en el parámetro-s. Luego se procede como ya habíamos visto antes. De esta forma pv es capaz de determinar cuánto falta y muestra que la ejecución tardará apróximadamente unos 4 minutos y 49 segundos hasta terminar.

Otro caso muy útil es la combinación de pv con nc (de la cual se hablará un poco próximamente ;) para copiar grandes cantidades de datos a través de una red local. Para ilustrar este caso supongamos que tenemos dos computadoras A y B. Se desea copiar un directorio desde A hacia B lo más rápido posible. El modo más eficiencia resulta ser sin dudas el uso combinado de tar y nc ... y pv estará ahí para monitorearlo todo ... :)

# en la computadora A, con IP 172.18.1.100
$ tar -cf - /path/to/dir | pv | nc -l -p 6666 -q 5

# en la computadora B
$ nc 172.18.1.100 6666 | pv | tar -xf -

Y esto es todo. Todos los ficheros en el directorio situado en la computadora de orígen A serán copiados hacia el destinatario B, y Ud será testigo de cuán rápido resulta toda la operación. Si desea ver la barra de progreso, se puede recurrir al truco mostrado más arriba pv -s $( ). Ahora, esto solo será efectivo en el caso de la computadora de orígen A.

Y ya para concluir se puede tener una idea de la rapidez con que la PC lee del dispositivo especial /dev/zero:

$ pv /dev/zero > /dev/null
59.7GB 0:00:08 [ 7.5GB/s] [        <=>             ]

Y esto es todo, al menos por ahora, porque no faltará una respuesta en caso de alguna duda. Ud podrá además revelar otros usos interesantes del comando pv ... espero sus comentarios.

¿Cómo se instala pv?

Los usuarios de Debian o sistemas afines (e.g. Ubuntu) lo hacen así:

$ sudo apt-get install pv

En Fedora or distribuciones basadas en Fedora (e.g. CentOS sería algo así:

$ sudo yum install pv

Estando en Slackware, se hace necesario visitar el sitio de pv, descargar el archivo pv-version.tar.gz y luego compilar los fuentes:

$ tar -zxf pv-version.tar.gz
$ cd pv-version
$ ./configure && sudo make install

Los usuarios de Mac harían algo semejante a:

$ sudo port install pv

... mientras que los de OpenSolaris:

$ pfexec pkg install pv

Si utilizamos Cygwin en Windows:

$ ./configure
$ export DESTDIR=/cygdrive/c/cygwin
$ make
$ make install

... y siempre tenemos la opción de leer el manual de pv.

Espero que les haya gustado este artículo; y, como siempre, espero sus comentarios llenos de sugerencias y de propuestas para abordar otros comandos en el futuro. Simelo pide no faltará un espacio para abordar las dudas que hace tanto tiempo le inquietan. Vea los comandos de su preferencia en acción, en vivo y en directo, aquí ... en el blog de Simelo.

1 comentario:

  1. Estupendo tutorial, las posibilidades de linux son infinitas....
    Saludos.

    ResponderEliminar