Tengo un script de perl que, cuando destilada un poco, se ve así:Verificando un túnel SSH está funcionando
my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background
sleep 10; # Give the tunnel some time to come up
# Create the telnet object
my $telnet = new Net::Telnet(
Timeout => 10,
Host => 'localhost',
Port => $randport,
Telnetmode => 0,
Errmode => \&fail,
);
# SNIPPED... a bunch of parsing data from $telnet
La cosa es que el objetivo $ ip está en un enlace con muy impredecible ancho de banda, por lo que el túnel podría aparecer de inmediato, podría tomar un tiempo, podría no aparecer en absoluto. Por lo tanto, es necesario dormir para que el túnel pueda comenzar a funcionar.
Entonces la pregunta es: ¿cómo puedo probar si el túnel está funcionando? 10 segundos es una demora realmente indeseable si el túnel aparece de inmediato. Idealmente, me gustaría verificar si está activo y continuar creando el objeto telnet una vez que esté, hasta un máximo de, digamos, 30 segundos.
Editar: Ping no me ayuda a Mouch, como el extremo remoto del túnel es generalmente hacia arriba, pero con una cantidad muy alta de pérdida de paquetes
resuelto: Extrapolando a partir de la punta sugerido por mikebabcock , sleep 10
se ha sustituido con este bloque, que funciona como un encanto:
my $starttime = time();
while (1)
{
# Check for success
if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }
# Check for timeout
if (time() > $starttime + 30) { &fail() }
# 250ms delay before recheck
select (undef, undef, undef, 0.25);
}
Como está utilizando el módulo 'Net :: Telnet', ¿ha intentado utilizar la llamada' open' y probar si tiene éxito? No soy un experto en Telnet, pero eso es lo que probablemente probaría si fuera yo ... –
Podría hacer eso si no hay una manera simple de probar: vuelva a intentar hasta el éxito si time_spend_trying <30 seconds – Jarmund