vt - medir el volumen de datos transferido

Nombre: vt
Autor: Patricio Silva (Pato Silva)
Lenguaje: perl
Licencia: GPL
Propósito: recibe datos por la entrada estandar y los envia nuevamente por la salida estandar mientras por la salida de error estandar muestra información acerca de la transferencia de datos, emite un beep al terminar.
Sinopsis:

vt [TAMAÑO_ESTIMADO_DEL_VOLUMEN] [--beep | --no-beep]

  • TAMAÑO_ESTIMADO_DEL_VOLUMEN: Tamaño estimado en bytes del volumen a transferir. Si se especifica se emitira un progreso de transferencia acorde al valor dado. Se puede especificar el valor en kilobytes, megabytes o gigabytes agregando la inicial correspondiente.
  • --no-beep: No emitir beep al terminar (por defecto siempre se emite beep)
  • --beep: Emitir un beep fuerte (diez repeticiones de larga duración y a alta frecuencia)

Dependencias: perl, beep (opcional)

Código:

#!/usr/bin/perl
# @author Pato Silva
# @date 30 de Mayo de 2009
# @version 1.0

use strict;

# Buffer de lectura
my $buffer;

# Marca de tiempo de inicio de transferencia
my $ini_t = time();

# Marca de tiempo en un mometo dado
my $prog_t = time();

# Tamaño estimado del volumen a transferir
my $size = 0;

# Bytes actualmente transferidos
my $current = 0;

sub human_readable{
my $value = shift;
my $human = $value . ' B';
if($value > 1073741824){
my @giga = split(/\./, ($value/1073741824));
$human = substr("   " . $giga[0], -4) . '.' . substr($giga[1] . "00", 0, 2) . 'GB';
}elsif($value > 1048576){
my @mega = split(/\./, ($value/1048576));
$human = substr("    " . $mega[0], -5) . '.' . substr($mega[1] . "00", 0, 2) . 'MB';
}elsif($value > 1024){
my @kilo = split(/\./, ($value/1024));
$human = substr("    " . $kilo[0], -5) . '.' . substr($kilo[1] . "00", 0, 2) . 'KB';
}
return $human;
}

# Determinacion del tamaño de acuerdo a comodines
if($ARGV[0] =~ /^\d+[G|g]$/){
$size = $ARGV[0]*1073741824;
}elsif($ARGV[0] =~ /^\d+[M|m]$/){
$size = $ARGV[0]*1048576;
}elsif($ARGV[0] =~ /^\d+[K|k]$/){
$size = $ARGV[0]*1024;
}elsif($ARGV[0] =~ /^\d+$/){
$size = $ARGV[0];
}

# Lectura en bloques de un mega
while(read(STDIN, $buffer, 1048576)){
print $buffer;
$current += length($buffer);

# Retorno de carro
print STDERR "\r";

# Velocidad de transferencia
if(time() > $ini_t){
print STDERR human_readable($current/(time()-$ini_t)) . "/s";
}else{
print STDERR "    0.00 B/s";
}

# Volumen transferido
print STDERR human_readable($current);

# Progreso de la transferencia
if($size > $current){
print STDERR "    [" . substr("  " . int($current*100/$size), -3) . "%]";
}else{
print STDERR "    [ ? %]";
}
}

# Información sumaria una vez finalizada la transferencia
print STDERR "\r" . human_readable($current) . " transferidos en " . (time()-$ini_t) . " segundos (" . human_readable($current/((time()>$ini_t)?time()-$ini_t:1)) . "/s)\n";

# Determina si se debe hacer beep al terminar
if($ARGV[0] =~ /^--beep$/ || $ARGV[1] =~ /^--beep$/){
system("beep -f 2700 -d 500 -r 10 -l 500");
}elsif($ARGV[0] !~ /^--no-beep$/ && $ARGV[1] !~ /^--no-beep$/){
system("beep -f 2500 -d 200 -r 3 -l 200");
}

exit(0);

Ejemplos de uso:

  • cat foo | vt 700m > bar - Copia el contenido del archivo foo en bar, muestra el progreso de copia asumiendo que el archivo foo tiene un tamaño de 700 Megabytes y emite tres beeps cortos al terminar.
  • dd if=/dev/sda bs=1024k | vt 160g --beep | gzip --best > disk.img.gz - Crea un archivo comprimido que contiene una imagen del disco /dev/sda, muestra el progreso de la copia asumiendo un tamaño de 160 Gigabytes y emite 10 fuertes beeps al termina.

Comentarios: