Debian - comment exécuter un script au démarrage dès qu'une connexion Internet est prête à l'emploi?

14

J'utilise Debian 7 Wheezy et j'ai besoin de démarrer certains écrans au démarrage dès qu'il y a une connexion Internet entièrement fonctionnelle. Cependant, non, si la connexion Internet est rompue et est à nouveau connectée. Donc, uniquement sur la première connexion Internet fonctionnelle après le démarrage.

Pourriez-vous s'il vous plaît poster un script factice pour cela et me dire où le mettre et le faire exécuter dans les conditions données?

Le script n'a besoin que de démarrer l'écran puis de se terminer mais l'écran doit continuer.


EDIT J'ai déjà entendu parler du /etc/network/if-up.d/dossier. Mais comment puis-je m'assurer que le script n'est pas exécuté à nouveau si la connexion Internet est perdue puis rétablie?

MinecraftShamrock
la source
@Celada s'il vous plaît voir l'édition
MinecraftShamrock

Réponses:

21

Mettez votre script /etc/network/if-up.det rendez-le exécutable. Il sera exécuté automatiquement chaque fois qu'une interface réseau apparaîtra.

Pour le faire fonctionner uniquement la première fois qu'il est exécuté à chaque démarrage, demandez-lui de vérifier l'existence d'un fichier indicateur que vous créez après la première fois. Exemple:

#!/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
la source
Le fichier de drapeau sera-t-il supprimé lors de l'arrêt du serveur?
MinecraftShamrock
1
Oui, car sur Debian /var/runest un système de fichiers volatile (a tmpfs). Il est donc garanti de se retrouver vide à chaque nouveau démarrage.
Celada
1
Bonne prise. Je pense que vous devriez être vraiment malchanceux, mais je pense que oui, à cause des interfaces enfichables à chaud qui pourraient être mises en place simultanément. Donc je suppose que vous pouvez le faire atomiquement au lieu de tester puis créer, ce qui le rendrait sûr, mais ce que j'ai trouvé du haut de ma tête n'est pas joli! 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 vous utilisez le script de Celada tel quel, votre code s'exécutera dès que l'interface de bouclage apparaîtra. Si vous voulez attendre la connectivité Internet, vérifiez au moins que ce IFACEn'est pas le cas lo- ou une interface virtuelle - ou mieux, testez la connectivité Internet en exécutant une commande ping.
Gilles 'SO- arrête d'être méchant'
1
@MinecraftShamrock $IFACEpeut avoir comme valeurs n'importe quelle interface qui apparaît. Vous pouvez répertorier toutes les interfaces qui existent avec ip linkou regarder celles qui sont configurées pour être mises en place par numérisation/etc/network/interfaces
Celada
9

C'est un travail très bien adapté systemd.

Exécution d'un script en tant que service systemd

Si votre système exécute systemd , vous pouvez configurer votre script pour qu'il s'exécute en tant que service systemd qui permet de contrôler le cycle de vie et l'environnement d'exécution, ainsi que les conditions préalables au démarrage du script, telles que le réseau en cours d'exécution.

Le dossier recommandé pour vos propres services est /etc/systemd/system/(une autre option est /lib/systemd/systemmais qui devrait normalement être utilisée pour les services OOTB uniquement).

Créez le fichier par exemple avec 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

Vous pouvez maintenant tester le service:

sudo systemctl start autossh

Vérification de l'état du service:

systemctl status autossh

Arrêt du service:

sudo systemctl stop autossh

Une fois que vous avez vérifié que le service fonctionne comme prévu, activez-le avec:

sudo systemctl enable autossh

REMARQUE: pour des raisons de sécurité, systemdle script s'exécutera dans un environnement restreint, similaire à la façon dont les crontabscripts sont exécutés, donc ne faites aucune hypothèse sur les variables système préexistantes telles que $ PATH. Utilisez les Environmentclés si votre script nécessite la définition de variables spécifiques. L'ajout set -xen haut de votre script bash puis son exécution systemctl status my_servicepeuvent aider à identifier la raison de l'échec de votre script. En règle générale, utilisez toujours des chemins absolus pour tout, y compris echoou définissez explicitement votre $ PATH en ajoutant Environment=MYVAR=abc.

ccpizza
la source
2

La connexion Internet est évoquée par une entrée dans /etc/rc6.d/probablement S35networking. Si vous modifiez ce fichier et insérez vos commandes à la fin, ou mieux ajoutez un /etc/init.d/mystufflien /etc/rc0.d/S36mystuffvers celui-ci et insérez-y vos commandes, alors cela démarrera dès que le réseau sera en place.

Anthon
la source
Sera-t-il appelé si la connexion est perdue puis rétablie? Parce que sinon, je pourrais simplement mettre le script dans/etc/network/if-up.d
MinecraftShamrock
Non, ce n'est qu'au démarrage
Anthon
1
Cela fonctionnera, mais pour plus de précision, permettez-moi de souligner qu'aucun script dans /etc/rc0.dne sera exécuté au démarrage, ceux-ci s'exécuteront à l'arrêt (niveau d'exécution 0). Au démarrage, ce serait quelque chose /etc/rc2.dou similaire. Spécifiquement pour le sifflement Debian de l'OP, c'est /etc/rcS.d/S12networking. Bien sûr, tous les liens symboliques vers le même fichier. BTW @Anthon aussi merci d'avoir corrigé ma réponse: "S'il vous plaît" au lieu de "Mettre"? Quelle coquine bizarre!
Celada
@Celada Votre droit c'est rc6 sur mon (système non Debian). Je ne savais pas si vous vouliez mettre «S'il vous plaît», mais juste «Put» semblait plus croustillant. BTW J'ai voté pour votre réponse, c'est juste une meilleure approche pour le réseautage car il a cela if-up.dcomme mécanisme générique qui fonctionne également sur une reconnexion.
Anthon