4 votes

Comment afficher l'adresse IP à l'écran de connexion dans Arch Linux

J'ai pu le faire dans Ubuntu en modifiant le fichier :

/etc/rc.local

et ajouter :

IP=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')

echo "IP: $IP" > /etc/issue

Dans Arch, ce fichier n'existe pas "/etc/rc.local" et après quelques recherches j'ai trouvé que je dois créer ce fichier :

/etc/systemd/system/rc-local.service

Contenu :

[Unit]
Description=/etc/rc.local compatibility

[Service]
Type=oneshot
ExecStart=/etc/rc.local

TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

Ensuite, Créez "/etc/rc.local".

Contenu :

IP=$(/sbin/ip route get 1 | awk '{print $NF;exit}')
echo "IP: $IP" > /etc/issue

exit 0

Ensuite, Rendez-le exécutable :

sudo chmod +x /etc/rc.local

Et enfin démarrez/testez :

sudo systemctl start rc-local.service

Obtention de l'erreur :

Le travail pour rc-local.service a échoué car le processus de contrôle s'est terminé avec un code d'erreur.
Voir "systemctl status rc-local.service" et "journalctl -xe" pour plus de détails.

Sortie de systemctl status rc-local.service :

* rc-local.service - /etc/rc.local Compatibilité
Chargé: chargé (/etc/systemd/system/rc-local.service; activé; préfixe du vendeur : désactivé)
Actif: échoué (Résultat: code de sortie) depuis le ven. 2016-06-10 02:52:17 AST; il y a 1min 59s
Processus: 760 ExecStart=/etc/rc.local (code=exited, status=203/EXEC)

10 juin 02:52:17 maro systemd[1]: Démarrage de /etc/rc.local Compatibilité...
10 juin 02:52:17 maro systemd[1]: rc-local.service: Le processus de contrôle s'est terminé, code=exited status=203
10 juin 02:52:17 maro systemd[1]: Échec de la compatibilité de /etc/rc.local.
10 juin 02:52:17 maro systemd[1]: rc-local.service: L'unité est entrée dans un état échoué.
10 juin 02:52:17 maro systemd[1]: rc-local.service: Échec avec le résultat 'code de sortie'.

Sortie de journalctl -xe :

-- L'unité rc-local.service a commencé à démarrer.
10 juin 02:52:17 maro systemd[760]: rc-local.service: Échec à l'étape DÉMARRAGE spawn /etc/rc.local: Erreur de format d'exécution
-- Sujet : Le processus /etc/rc.local n'a pas pu être exécuté
-- Défini par : systemd

Mise à jour :

  1. Ajouté #!/bin/bash à /etc/rc.local
  2. sudo systemctl daemon-reload
  3. sudo systemctl start rc-local.service
  4. Maintenant je n'obtiens plus d'erreurs ! mais :
  5. sudo systemctl status rc-local.service Sortie :

    rc-local.service - /etc/rc.local Compatibilité Chargé: chargé (/etc/systemd/system/rc-local.service; activé; préfixe du vendeur : désactivé) Actif: inactif (mort) depuis le ven. 2016-06-10 13:13:04 AST; il y a 3s Processus: 488 ExecStart=/etc/rc.local (code=exited, status=0/SUCCESS)

    10 juin 13:13:04 maro systemd[1]: Démarrage de /etc/rc.local Compatibilité... 10 juin 13:13:04 maro systemd[1]: Démarré /etc/rc.local Compatibilité.

Essayé de redémarrer et avant de me connecter ça affiche :

rtnetlink answers network is unreachable

À l'écran de connexion : ça affiche seulement "IP:" sans afficher l'IP de la machine. Une fois connecté et ping google par exemple, internet fonctionne sans problème et la machine est accessible via le LAN.


  1. sudo env -i /etc/rc.local = Aucune sortie
  2. ip route get 1 | awk '{print $NF;exit}' qui est utilisé dans /etc/rc.local = 192.168.0.103

Sortie de nav :

XDG_SESSION_ID=c2
TERM=xterm
SHELL=/bin/bash
SSH_CLIENT=192.168.0.100 64436 22
SSH_TTY=/dev/pts/0
USER=maro
MAIL=/var/spool/mail/maro
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
PWD=/home/maro
LANG=C
SHLVL=1
HOME=/home/maro
LOGNAME=maro
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
SSH_CONNECTION=192.168.0.100 64436 192.168.0.103 22
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/env

Édité /etc/systemd/system/rc-local.service : Supprimer quatre paramètres après ExecStart. J'ai également essayé de changer : Type=forking

Le statut indique toujours : Actif: inactif (mort)

0 votes

Il semble que vous vouliez afficher l'adresse IP, et non l'IP, comme vous l'avez demandé dans la question. Vous n'avez que deux IPs possibles : IPv4 et IPv6.

0 votes

@RonMaupin, Désolé pour l'erreur, je veux afficher l'adresse IP interne. Y a-t-il une erreur dans mes étapes ou code bash ?

5voto

PaoloC Points 251

Sur CentOS 7 et Debian 8 (et peut-être d'autres également), il suffit d'ajouter la ligne suivante à /etc/issue

Mon adresse IP : \4

qui résoudra à l'adresse IPv4 de la machine. Si vous avez plusieurs interfaces réseau et que vous souhaitez en choisir une spécifique, vous pouvez le spécifier avec

Mon adresse IP : \4{eth0}

0 votes

Super réponse simple. Fonctionne également sur Arch Linux

0voto

Argonauts Points 4250

Je suis à 99% sûr que c'est parce que vous n'avez pas appelé l'interpréteur dans le script.

/etc/rc.local:

#!/bin/bash

IP=$(/sbin/ip route get 1 | awk '{print $NF;exit}')
echo "IP: $IP" > /etc/issue

exit 0

Cela devrait probablement fonctionner. Beaucoup de gens mentionnent également explicitement bash dans leur fichier système; j'ai modifié votre fichier de service. Je mentionne ceci ci-dessous, mais 4 des paramètres ne sont pas nécessaires (à ma connaissance) et je les ai également supprimés ici :

/etc/systemd/system/rc-local.service:

[Unit]
Description=Compatibilité avec /etc/rc.local

[Service]
Type=oneshot
ExecStart=/bin/bash /etc/rc.local

[Install]
WantedBy=multi-user.target

Vous devriez également utiliser le chemin complet de awk, mais cela générerait une erreur différente - vous n'êtes pas encore allé si loin dans le script.

Si cela n'a pas corrigé le problème, vous devrez procéder étape par étape et voir ce qui fonctionne individuellement. L'environnement systemd est très limité (similaire aux choses lancées depuis cron, mais avec moins d'environnement). Des choses qui fonctionnent toujours cessent de fonctionner en raison d'un paramètre environnemental qui est toujours défini, donc nous oublions que cela doit même être défini. Essayez d'isoler un problème lié à cela. Voici quelques étapes d'isolation :

  1. Exécutez directement (avec sudo ou dans un shell root pour chaque étape) /etc/rc.local depuis un terminal.

  2. Si cela fonctionne, essayez de l'exécuter comme env -i /etc/rc.local. Si cela ne fonctionne pas, vous pouvez essayer de passer des valeurs environnementales une par une, ou avoir votre script qui les force à être définies (fortement déconseillé, mais si vous en avez envie, vous pourriez mettre la sortie de env dans un shell 'normal', env | sed 's/^/export /g' | sed 's/=/='/g' | sed -e 's/$/'/g' > env_values.sh et définir explicitement ces valeurs dans le script.. Vous devez nettoyer un peu la liste - elle aura des valeurs de connexion ssh et d'autres entrées déclenchées par des événements qui ne casseraient probablement rien mais n'aideront certainement pas).

  3. Si ce n'est pas ça car peu importe comment vous exécutez rc.local, cela fonctionne simplement, je simplifierais votre fichier de service systemd. Essayez sans eux.

    • La configuration reste après la définition de sortie n'est pas pertinente ici - cela concerne l'utilisation de ceci pour appeler un script unique qui lance des démons.
    • Le paramètre tty est un cas très spécial, et n'est pas nécessaire.
    • Le paramètre de délai d'attente de 0 peut entraîner des systèmes bloqués lors des cycles de mise sous tension.
    • La priorité de démarrage de SysV est obsolète sur systemd ver > 218+; arch est sur au moins la ver 229.
  4. Essayez d'utiliser un @reboot cronjob. Environnement très similaire, mais je le trouve moins 'capricieux'. @reboot remplace la méthode normale des 5 astérisques pour le timing (par exemple au lieu de 0 0 0 * * vous mettez simplement @reboot), et votre script sera appelé à chaque démarrage. Si vous avez besoin d'aide supplémentaire pour configurer un cronjob je peux certainement fournir plus de détails.

Je ne vois aucun problème avec votre méthode pour obtenir votre IP lan. Voici une méthode différente à essayer si cela pose des problèmes. Le vôtre est probablement meilleur. il a moins de dépendances et certainement plus propre, mais j'utilise cette approche depuis des années sans problème :

iprgx='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
cat /etc/hostname | /usr/bin/host -4r | grep -Eo "$iprgx"

Si tout cela échoue, vous devrez lire la documentation de systemd... ce qui, comme vous l'avez probablement découvert, est très long en termes de mots et incroyablement pauvre en informations spécifiques. Faites-moi savoir ce que vous découvrez même si ces idées ne fonctionnent pas - il pourrait y avoir un indice dans les résultats malgré tout.

Mise à jour

Conformément à votre mise à jour, les modifications apportées au service permettent au script de s'exécuter correctement. L'état que vous obtenez est normal pour un événement unique - les services systemd sont vraiment axés sur les processus de démon qui sont lancés, et vous ne faites pas cela - donc (en simplifiant beaucoup), il dit essentiellement qu'il est inactif, ce qui signifie que le script ne fonctionne pas encore, n'est pas prévu pour s'exécuter, et n'a pas lancé de processus que systemd suit - ce qui est correct et acceptable. Le fait qu'il montre qu'il s'est exécuté récemment et qu'il s'est terminé en SUCCESS signifie que cela fonctionne.

Le deuxième problème est le timing relatif. La réponse concise est que vous devrez modifier votre fichier de service en ajoutant les deux entrées suivantes sous [Unit]. Cela pourrait simplement fonctionner. Sinon, lisez la suite.

[Unit]
Wants=network-online.target
After=network-online.target

Il existe un excellent article sur ce problème spécifique sur stackexchange Ils semblent avoir couvert toutes les manières dont cela peut mal tourner et comment cela peut bien se passer de la mauvaise manière... Je ne vais pas essayer de le relayer - obtenez simplement des informations d'un gourou apparent.

Approche alternative qui a l'avantage de rendre les fans de systemd furieux

Si cette approche devient difficile ou impossible pour quelque raison que ce soit, voici une méthode beaucoup moins élégante et brutale à laquelle je me tourne souvent quand ma patience avec systemd est épuisée :

Vous pouvez modifier votre script pour attendre que l'adresse IP devienne disponible elle-même au lieu de vous enliser dans les problèmes de synchronisation précédents / suivants. C'est un hack car il réimplémente délibérément une fonctionnalité qui est intégrée à systemd, mais c'est ce que je ferais probablement.

J'ai mis à jour ce script (essayé de l'exécuter et trouvé quelques problèmes). Celui-ci fonctionne bien sur mon système. J'avais utilisé la syntaxe de la fonction C sur l'appel de sommeil, et oublié en fait de retourner quoi que ce soit de getIP; les deux ont été corrigés.

/etc/rc.local

#!/bin/bash   

iprgx='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'

# J'ai mis cela dans une fonction car vous allez boucler dessus.
# l'erreur que vous voyez est due à l'appel ip - je redirige l'erreur vers
# /dev/null pour me débarrasser de cette nuisance.
getIP() {
  echo "IP=$(/sbin/ip route get 1 2>/dev/null | awk '{print $NF;exit}' | grep -Eo "$iprgx")"
}

# chronomètre du watchdog - arrêt s'il ne se résout pas après un certain delta-T
wdTimer=1
IP=$(getIP)
#echo "($wdTimer) IP: $IP"
while [ "$IP" == "" ]; do
  # Il n'y a rien de spécial à propos de 0.5 seconde - cela semblait simplement raisonnable
  sleep 0.5
  IP=$(getIP)
  #echo "($wdTimer) IP: $IP"
  ((wdTimer++))
  # Délai arbitraire de 20 * 0,5 = 10 secondes
  # Vous pouvez le faire attendre aussi longtemps que vous le souhaitez. Je suggère de ne pas
  # régler le temps d'attente trop bas car vous allez fortement solliciter le
  # l'utilitaire ip dans ce cas; pas énorme, peu importe
  # Je l'ai également incité à enregistrer quelque chose dans le syslog - à modifier selon votre convenance
  # avec logger - il existe d'autres façons de le faire.
  if [ "$wdTimer" -gt "20" ]; then
    # temporisé
    logger -s "Temps écoulé en essayant d'acquérir une IP LAN dans rc.local"
    exit 1
  fi
done
#echo "IP: $IP" #> /etc/issue
exit 0

Et oui, j'utilise ce regex $iprgx tout le temps - super utile.

0 votes

Je suis vraiment reconnaissant de votre excellente réponse, j'ai essayé et ai posté les résultats dans ma question pour une meilleure mise en forme.

0 votes

Je pensais qu'il y aurait des problèmes cachés derrière le premier. Donc le script s'exécute maintenant; il s'exécute juste trop tôt au démarrage. Je mets plus d'infos dans ma réponse

0 votes

Il n'y a actuellement aucune erreur mais lors de la vérification du statut, il indique : Actif : inactif (éteint) il y a 3 secondes. Est-ce qu'il pourrait rester actif/en cours pendant quelques minutes par exemple ? Afin de résoudre le problème ?

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X