0 votos

Ayuda para escribir un AppleScript que espere un Ping

Estoy tratando de hacer que un AppleScript espere hasta que haya un ping exitoso de una IP o URL local antes de continuar. Quiero que esto funcione sin WiFi o ethernet y básicamente, estar reintentando hasta que una de esas conexiones esté en funcionamiento.

El problema es que "do shell script" devuelve un error de host desconocido si no hay conexión de red y rompe mi script.

Aquí está mi punto de partida script:

set ping to do shell script "ping -c 2 -q google.com"

repeat until ping contains "2 packets received"

   delay 1

end repeat
display dialog "Connection Successful." buttons {"OK"} default button 1

He probado a añadir comandos "try" y "repeat until" pero nada consigue evitar ese error.

Se agradece cualquier ayuda.

2voto

Nate Puntos 220

El primer problema es que estás ejecutando el ping prueba una vez al principio, almacenando el resultado, y luego simplemente comprobando ese mismo resultado una y otra vez. Pero es un resultado almacenado, por lo que nunca va a cambiar a menos que vuelva a ejecutar la prueba.

En segundo lugar, se necesita un try para capturar los errores del ping comando. De hecho, no es necesario almacenar el resultado en absoluto, sólo utilizar el hecho de que si el ping falla, se saltará el resto de la try sección. Algo así:

repeat
    try
        do shell script "ping -c 2 -q www.google.com"
        exit repeat
    on error
        delay 1
    end try
end repeat
display dialog "Connection Successful." buttons {"OK"} default button 1

...así que si el ping tiene éxito, ejecutará el exit repeat comando. Si no lo hace, ejecuta el on error que retrasa un segundo (y no lo hace salir de la repeat para que el bucle se ejecute de nuevo).

[EDITAR] Si quieres que se agote el tiempo después de 10 segundos, puedes grabar la hora de inicio al principio, y luego cada vez que el ping falla al comprobar si han pasado más de 10 segundos y mostrar el mensaje de fallo si es así. La otra cosa que hay que cambiar es que, dado que el mensaje "Conexión exitosa." sólo debe mostrarse si tuvo éxito, no si salió del bucle debido al tiempo de espera, ese mensaje debe moverse a la condición de "éxito" dentro del bucle:

establecer startTime como (fecha actual)

repeat
    try
        do shell script "ping -c 2 -q www.google.com"
        display dialog "Connection Successful." buttons {"OK"} default button 1
        exit repeat
    on error
        if ((current date) - startTime) > 10 then
            display dialog "Connection timed out." buttons {"OK"} default button 1
            exit repeat
        else
            delay 1
        end if
    end try
end repeat

(Nota: puede ser tentador utilizar repeat while ((current date) - startTime) > 10 pero eso hace más difícil saber si el bucle salió por éxito o por un tiempo de espera. En mi opinión, es más sencillo incluir la condición de detección de finalización, el mensaje de visualización y la salida del bucle como bloques dentro del bucle).

1voto

qarma Puntos 71

Me meto en esto un poco tarde, pero he leído las ganas que tienes de aprender AppleScript y similares, así que pensé que te gustaría ver un enfoque de tu problema que se resuelve puramente con AppleScript.

El problema, tal y como lo planteas, es la necesidad de determinar si un host remoto es alcanzable, lo que supongo que es un medio para determinar si tu máquina tiene o no acceso a Internet. En su ejemplo, usted ha establecido esto por ping 'ing google.com .

En lugar de hacer ping a un host, basta con ver si su nombre de host se resuelve.

La jerga técnica: A nombre del anfitrión es la forma canónica y legible de un host remoto (como "google.com"), pero para poder conectarse a él, primero debe transformarse (resolverse) en una dirección IP (como 142.250.187.195), que proporciona a una máquina la ubicación del host en Internet. Esto se denomina resolución de nombres de host o resolución de nombres de dominio y es realizado por un servidor de nombres de dominio .

Si un nombre de host remoto se resuelve con éxito, entonces tiene acceso a Internet, y muy probablemente, su script puede seguir adelante. El beneficio de este método comparado con un ping es que el ping depende de que el host remoto esté en funcionamiento y conectado a Internet (por supuesto, Google probablemente no se ha desconectado desde los años 90); y requiere que el host al que se le hace el ping elija responder al ping (no está obligado a hacerlo). La resolución de DNS se producirá independientemente de que el host responda o no, y es una acción necesaria que debe producirse para que tu máquina pueda acceder a Internet. Si falla, entonces es probable que no puedas acceder a ningún sitio web, lo que en tu caso parece una prueba razonable para determinar si alguna de tus conexiones ethernet está activa.

De todos modos, aquí está el manejador de AppleScript:

on hostIsReachable at address as {record, text}
        tell (the address as {URL, anything}) to if ¬
                    (string != its class) then tell ¬
                    the host to set the address to ¬
                    the DNS form

        tell ("mailto:" & the address) as URL to tell ¬
                    host & {dotted decimal form:stop} ¬
                    to its dotted decimal form != stop
end hostIsReachable

Puedes pegar esto al principio o al final de tu script donde puede que ya tengas otros manejadores al acecho. El manejador puede ser invocado siempre que necesites usarlo así:

hostIsReachable at "https://www.google.com" --> true

o:

hostIsReachable at "google.com" --> true

o:

hostIsReachable at "google" --> true

Devuelve true si el nombre de host o la URL que ha suministrado es uno que se espera que se resuelva y tiene una conexión a Internet activa para que la resolución tenga lugar; devuelve false de lo contrario. Entonces, esto:

hostIsReachable at "asdfghjkl.com" --> false

devolverá false porque ese nombre de dominio no está registrado en Internet. Además, el uso de una dirección IP siempre devolverá true Lo cual tiene sentido si se tiene en cuenta que la naturaleza de la prueba es determinar si obtenemos una dirección IP de vuelta después de alimentar algunos datos - si esos datos ya son una dirección IP, entonces no hay mucho que resolver.

Puede incluir esta prueba en un bucle de sondeo:

repeat 20 times -- 20 × 0.5-second delays = 10 seconds
        set connected to hostIsReachable at "google.com"
        if connected then exit repeat
        delay 0.5 -- (in seconds)
end repeat

if not connected then error "Timeout waiting for connection."
            .
            .
            .
(* rest of your script *)

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X