Debian: ¿cómo ejecutar un script al inicio tan pronto como haya una conexión a Internet lista para usar?

14

Estoy ejecutando Debian 7 Wheezy y necesito iniciar algunas pantallas al inicio tan pronto como haya una conexión a Internet completamente funcional. Sin embargo, no, si la conexión a Internet se rompió y se volvió a conectar. Entonces, solo en la primera conexión a Internet funcional después del arranque.

¿Podría publicar un script ficticio para esto y decirme dónde colocarlo y hacer que se ejecute en las condiciones dadas?

El script solo necesita iniciar la pantalla y luego finalizar, pero la pantalla debe continuar.


EDITAR Ya he oído hablar de la /etc/network/if-up.d/carpeta. Pero, ¿cómo puedo asegurarme de que el script no se ejecute nuevamente si se pierde la conexión a Internet y luego se restablece?

MinecraftShamrock
fuente
@Celada, mira la edición
MinecraftShamrock

Respuestas:

21

Pon tu script /etc/network/if-up.dy hazlo ejecutable. Se ejecutará automáticamente cada vez que aparezca una interfaz de red.

Para que funcione solo la primera vez que se ejecuta en cada arranque, haga que compruebe la existencia de un archivo de marca que cree después de la primera vez. Ejemplo:

#!/bin/sh

FLAGFILE=/var/run/work-was-already-done

case "$IFACE" in
    lo)
        # The loopback interface does not count.
        # only run when some other interface comes up
        exit 0
        ;;
    *)
        ;;
esac

if [ -e $FLAGFILE ]; then
    exit 0
else
    touch $FLAGFILE
fi

: here, do the real work.
Celada
fuente
¿Se eliminará el archivo de bandera cuando el servidor se apague?
MinecraftShamrock
1
Sí, porque en Debian /var/runhay un sistema de archivos volátil (a tmpfs). Por lo tanto, se garantiza que estará vacío en cada arranque nuevo.
Celada
1
Buena atrapada. Creo que tendría que ser realmente desafortunado, pero creo que sí, debido a las interfaces conectadas en caliente que podrían abrirse simultáneamente. Así que supongo que puedes hacer esto atómicamente en lugar de probar y luego crear, lo que lo haría seguro, ¡pero lo que se me ocurrió en la cabeza no es bonito! python -c 'import os; os.open("/var/run/work-was-already-done", os.O_EXCL|os.O_CREAT, 0)' 2>/dev/null || exit 0
Celada
3
@MinecraftShamrock Si usa el script de Celada tal cual, su código se ejecutará tan pronto como aparezca la interfaz de bucle invertido. Si desea esperar la conectividad a Internet, al menos verifique que IFACEno sea lo, o alguna interfaz virtual, o mejor, pruebe la conectividad a Internet haciendo ping.
Gilles 'SO- deja de ser malvado'
1
@MinecraftShamrock $IFACEpuede tener como valores cualquier interfaz que aparezca. Puede enumerar todas las interfaces que existen ip linko ver cuáles están configuradas para que se muestren mediante escaneo/etc/network/interfaces
Celada
9

Este es un trabajo muy adecuado para systemd.

Ejecutar un script como un servicio systemd

Si su sistema ejecuta systemd , puede configurar su script para que se ejecute como un servicio systemd que proporciona control sobre el ciclo de vida y el entorno de ejecución, así como las condiciones previas para iniciar el script, como la red en funcionamiento.

La carpeta recomendada para sus propios servicios es /etc/systemd/system/(otra opción es /lib/systemd/systempero que normalmente debería usarse solo para servicios OOTB).

Cree el archivo, por ejemplo, con sudo vim /etc/systemd/system/autossh.service:

[Unit]
# By default 'simple' is used, see also https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
# Type=simple|forking|oneshot|dbus|notify|idle
Description=Autossh keepalive daemon
## make sure we only start the service after network is up
Wants=network-online.target
After=network.target

[Service]
## here we can set custom environment variables
Environment=AUTOSSH_GATETIME=0
Environment=AUTOSSH_PORT=0
ExecStart=/usr/local/bin/ssh-keep-alive.sh
ExecStop=pkill -9 autossh
# don't use 'nobody' if your script needs to access user files
# (if User is not set the service will run as root)
#User=nobody

# Useful during debugging; remove it once the service is working
StandardOutput=console

[Install]
WantedBy=multi-user.target

Ahora puedes probar el servicio:

sudo systemctl start autossh

Comprobación del estado del servicio:

systemctl status autossh

Detener el servicio:

sudo systemctl stop autossh

Una vez que haya verificado que el servicio funciona como se esperaba, habilítelo con:

sudo systemctl enable autossh

NOTA: Por razones de seguridad systemd, ejecutará el script en un entorno restringido, similar a cómo crontabse ejecutan los scripts, por lo tanto, no haga suposiciones sobre variables del sistema preexistentes como $ PATH. Use las Environmentteclas si su script necesita variables específicas para ser definidas. Agregar set -xen la parte superior de su script bash y luego ejecutarlo systemctl status my_servicepodría ayudar a identificar por qué su script falla. Como regla general de tumb, siempre use rutas absolutas para todo echo, incluso , o defina explícitamente su $ PATH agregando Environment=MYVAR=abc.

ccpizza
fuente
2

La conexión a internet es presentada por una entrada en /etc/rc6.d/probablemente S35networking. Si cambia ese archivo e inserta sus comandos al final, o mejor agregue un /etc/init.d/mystuffenlace /etc/rc0.d/S36mystuffa él e inserte sus comandos allí, entonces eso comenzará tan pronto como la red esté activa.

Anthon
fuente
¿Se llamará si se pierde la conexión y luego se restablece? Porque de lo contrario podría simplemente poner el script en/etc/network/if-up.d
MinecraftShamrock
No, esto es solo en el inicio
Anthon
1
Eso funcionará, pero solo por corrección, permítanme señalar que no /etc/rc0.dse ejecutará ningún script en el inicio, esos se ejecutarán en el apagado (nivel de ejecución 0). Al inicio, sería algo /etc/rc2.dsimilar o similar. Específicamente para el silbido Debian del OP, es /etc/rcS.d/S12networking. Todos los enlaces simbólicos al mismo archivo, por supuesto. También BTW @Anthon, gracias por arreglar mi respuesta: "¿Por favor" en lugar de "Put"? ¡Qué extraño error tipográfico!
Celada
@Celada Tu derecho es rc6 en mi (sistema no Debian). No estaba seguro de si querías 'Por favor, pon' allí, pero solo "Poner" parecía más crujiente. Por cierto, voté por su respuesta, es solo un mejor enfoque para la creación de redes, ya que tiene ese if-up.dmecanismo genérico que también funciona en una reconexión.
Anthon