alarm
establece un cronómetro. Cuando la
cuenta atrás termina el sistema operativo emite una señal
ALRM
, la cual puede ser interceptada por un manejador
de señales. Con un argumento 0
desactiva el cronómetro.
Este primer ejemplo pide al usuario un password, controlando si el tiempo
de lectura ha excedido un cierto límite:
$ cat time_exceeded.pl #!/usr/bin/perl -w use strict; my $deadline = (shift || 3); my $time_exceeded = 0; sub set_time_exceeded { $time_exceeded = 1; } $SIG{ALRM} = "set_time_exceeded"; print "Teclee su password: "; alarm($deadline); my $passwd = <STDIN>; alarm(0); print STDERR "Tiempo excedido.\n" if $time_exceeded;
El siguiente ejemplo utiliza eval
junto con las señales para
establecer un límite al tiempo de espera en una lectura:
> cat eval_alarm.pl #!/usr/bin/perl -w use strict; sub time_out { die "Cansados de esperar"; } my $lim = (shift or 3); my $buf; $SIG{ALRM} = "time_out"; eval { alarm($lim); # Le indica al SO enviar una señal de ALRM cada $lim s. $buf = <>; alarm(0); # Cancela la alarma }; if ($@ =~ /Cansados de esperar/) { print "Se acabo el tiempo para la entrada. ¡Adios muy buenas!\n" } else { print $buf; }Nótese que si la alarma se activa,
$@
contiene algo parecido a
"Cansados de esperar at eval_alarm.pl line 6"
, asi que no
se debe usar eq
sino una expresión regular.
Ejemplo de ejecución:
> eval_alarm.pl 2 Se acabo el tiempo para la entrada. ¡Adios muy buenas! > eval_alarm.pl 4 hola hola
En el siguiente ejemplo utilizamos esta estrategia para saber sobre la conectividad
de una máquina.
El comando ping
nos permite conocer los tiempos de respuesta.
La opción -c 1
limita el número de paquetes de prueba a uno.
Veamos un ejemplo de uso del comando ping
:
$ ping -c 1 etsii PING etsii (193.145.101.10): 56 data bytes 64 bytes from 193.145.101.10: icmp_seq=0 ttl=63 time=0.7 ms --- etsii ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.7/0.7/0.7 msEn este otro ejemplo vemos como es una respuesta negativa:
$ ping -c 1 miranda PING miranda (193.145.105.176): 56 data bytes --- miranda ping statistics --- 1 packets transmitted, 0 packets received, 100% packet lossEl comando
ping
en ocasiones no termina. En el siguiente ejemplo
se comprueba la conectividad de la máquina a través del mismo, limitando
el tiempo de espera por ping
.
$ cat -n myping.pl 1 #!/usr/bin/perl -w 2 3 use strict; 4 5 my @machines = @ARGV; 6 my ($m, $code) = ("", ""); 7 8 $SIG{ALRM} = 'kill_it'; 9 for $m (@machines) { 10 eval { 11 alarm(3); 12 $code = `ping -c 1 $m`; 13 alarm(0); 14 }; 15 if (defined($@) and ($@ =~ /too long/)) { 16 print "El acceso a $m toma demasiado tiempo.\n"; 17 my @ping = `ps -fA`; 18 my @pid = map { /(\d+)\s+$$\b.*\bping -c 1 $m\b/; $1 } @ping; 19 @pid = grep { defined($_) } @pid; 20 system('ps -fA | grep ping'); 21 print "Ejecutamos:\nkill 9, @pid\n" if @pid; 22 kill 9, @pid if @pid; 23 system('ps -fA | grep ping'); 24 } 25 else { 26 print "From $m:\ncode = $code\n\n"; 27 } 28 } 29 30 sub kill_it { die "too long"; } $ ./myping.pl miranda # máquin apagada lhp@nereida:~/Lperl/src$ ./myping.pl miranda # máquina apagada El acceso a miranda toma demasiado tiempo. lhp 6058 1899 0 16:16 pts/15 00:00:00 /usr/bin/perl -w ./myping.pl miranda lhp 6059 6058 0 16:16 pts/15 00:00:00 ping -c 1 miranda lhp 6061 6058 0 16:16 pts/15 00:00:00 sh -c ps -fA | grep ping lhp 6063 6061 0 16:16 pts/15 00:00:00 grep ping Ejecutamos: kill 9, 6059 lhp 6058 1899 0 16:16 pts/15 00:00:00 /usr/bin/perl -w ./myping.pl miranda lhp 6059 6058 0 16:16 pts/15 00:00:00 [ping] <defunct> lhp 6064 6058 0 16:16 pts/15 00:00:00 sh -c ps -fA | grep ping lhp 6066 6064 0 16:16 pts/15 00:00:00 grep ping $ ./myping.pl 193.145.105.253 # encendida From 193.145.105.253: code = PING 193.145.105.253 (193.145.105.253): 56 data bytes 64 bytes from 193.145.105.253: icmp_seq=0 ttl=64 time=2.0 ms --- 193.145.105.253 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 2.0/2.0/2.0 ms