Forum Programmation.shell Personnalisation du prompt bash

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
5
10
jan.
2021

J'ai besoin d'un peu d'aide d'un barbu charitable … ;-)

J'ai une poignée de RasPi dont je me sers pour tout et n'importe quoi.
J'ai du Zero, du 1B, du 2B, du 3B et du 3B+.

La plupart du temps, je m'y connecte en SSH, donc sans forcément être à proximité, et souvent je ne sais plus sur quel type de Pi je suis connecté.

J'aimerai beaucoup avoir cette information dans mon prompt Bash mais je suis trop ignare dans ce domaine pour arriver à mes fins.

Je sais récupérer le modèle du Pi en faisant

cat /proc/device-tree/model

mais le résultat est trop verbeux pour intégrer un prompt je trouve.

À la place de la sortie complète de la commande:

Raspberry Pi 2 Model B Rev 1.1

j'aimerai plutôt un truc court comme ceci

Pi2B

À-vot'bon-cœur.
(et bonne année à tous)

  • # echo

    Posté par  (site Web personnel) . Évalué à 2. Dernière modification le 10/01/21 à 20:30.

    Pourquoi ne rajoutes-tu pas simplement une ligne echo à ton .bashrc?

    echo "Pi2B"
    

    à adapter manuellement à chaque pi bien sûr. Sinon, tu peux aussi changer le hostname manuellement: https://linuxize.com/post/how-to-change-hostname-in-linux/

    Un LUG en Lorraine : https://enunclic-cappel.fr

    • [^] # Re: echo

      Posté par  . Évalué à 2. Dernière modification le 10/01/21 à 20:36.

      Tout simplement parce que ce qui est important pour moi, ce sont les IMG que je flashe sur les SD des Pi, pas les Pi en eux-même.

      Et bien entendu, je peux flasher ces IMG indifféremment sur du Zero, du 1B, du 2B ou whatever.

      C'est pour ça que je cherche une solution générique qui me renverrait dans le prompt le modèle du Pi, sans avoir besoin d'adapter à la main.

      Concernant le hostname, dans mon organisation il me sert à différencier une fonction, pas une machine physique.
      Par exemple la machine qui s'occupe de faire des timelapses se nomme 'pilapse'.
      Mais ce nom n'est pas définitivement alloué à une UC précise. Le Pi physique peut-être différent selon que je bidouille ceci ou cela

      • [^] # Re: echo

        Posté par  . Évalué à 2.

        Salut,

        Pas terrible, mais pour moi ça juste marche.

        J'ai ça dans mon .zshrc, que je copie, modifie, etc… à chaque nouvelle machine.

        Ok, pas bash, mais ça peut donner des pistes.

        autoload -U colors
        colors

        host_color="blue"
        #path_color="yellow"
        #date_color="red"
        date_color="green"

        date_format="%H:%M"
        date="%{$fg[$date_color]%}%D{$date_format}"
        host="%B%{$fg[$host_color]%}[%m]%b"
        cpath="%{$fg[$path_color]%}%~"
        end="%{$reset_color%}"

        PS1="$host$cpath$end\$ "
        RPS1="$date$end"

        (en gros, chaque machine+compte a sa couleur, et si ça vire vers le rouge, big warning du coup, là c'est plus root qu'utilisateur sudoer).

        Mais c'est peut-être pas ça que tu cherche, j'ai pas beaucoup de machines donc l'édition manuelle me prend moins de temps qu'un script.

        Matricule 23415

      • [^] # Re: echo

        Posté par  . Évalué à 5.

        Bonjour

        Pour obtenir la valeur raccourcie du modèle telle que tu la voulais :

        sed 's/Raspberry//;s/Model//;s/Rev.*//;s/ //g' < /proc/device-tree/model
        

        Le prompt affiché (qui dépends de la valeur de la variable PS1)
        est différent selon
        - le shell utilisé (bon, là c'est du bash)
        - le contenu du fichier ~/.bashrc
        - la valeur de la variable $TERM (qui dépends du terminal dans lequel s'affichera le prompt)
        - la valeur de la variable $USER
        - la valeur de la variable $HOSTNAME


        Si tu flashe la carte SD dans laquelle il y a le système d'exploitation,
        le fichier ~/.bashrc sera remplacé par celui contenu dans l'image flashée.

        Ce qui fait qu'après flashage, il te faudra refaire manuellement dans ~/.bashrc
        la modification qui permettait d'afficher le modèle de Pi.

  • # model…

    Posté par  . Évalué à 2.

    Je sais récupérer le modèle du Pi en faisant

    cat /proc/device-tree/model
    

    mais le résultat est trop verbeux pour intégrer un prompt je trouve.

    À la place de la sortie complète de la commande:

        Raspberry Pi 2 Model B Rev 1.1
    

    j'aimerai plutôt un truc court comme ceci

        Pi2B
    

    Première question : n'ayant pas de RasPi sous la main (encore qu'il me les faudrait tous), peux-tu préciser si la sortie complète est similaire pour les autres modèles ? En supposant que oui, ceci devrait répondre à ton besoin :

    # si un espace systématique entre chaque mot
    # attention, "cut" garde le délimiteur en sortie
    # d'où le "tr" pour tout concaténer
    cut -d ' ' -f 2,3,5 /proc/device-tree/model | tr -d ' '
    # si ce sont des espacements variables
    # attention, le séparateur de champ par défaut est l'espace en sortie
    awk '{print $2,$3,$5}' /proc/device-tree/model | tr -d ' '
    # on peut changer le séparateur de champ en sortie
    # mais on peut faire plus simple en n'ajoutant pas de séparateur de champs
    awk '{print $2 $3 $5}' /proc/device-tree/model

    Y a plus qu'à intégrer dans le reste de ton script.

    “It is seldom that liberty of any kind is lost all at once.” ― David Hume

    • [^] # Re: model…

      Posté par  . Évalué à 1.

      préciser si la sortie complète est similaire pour les autres modèles ?

      Oui, c'est le cas.

  • # Résolu !

    Posté par  . Évalué à 1. Dernière modification le 10/01/21 à 23:18.

    Fantastique, j'ai 2 solutions pour le prix d'une.
    Et maintenant j'ai un joli prompt qui s'adapte au modèle de RasPi qui l'exécute :-)

    21-01-10 23:07:56 pi@pilou (Pi2B):~ $

    21-01-10 23:12:18 pi@pignouf (Pi3B):~ $

    Merci beaucoup !

    (Note à moi même: faut vraiment que je me mette à sed et aux expressions régulières…)

    Concrètement, le bout de .bashrc qui fait le truc ressemble à ça:

    if [ -e /proc/device-tree/model ]; then
        MODEL=" ($(sed 's/Raspberry//;s/Model//;s/Rev.*//;s/ //g' < /proc/device-tree/model))"
    else
        MODEL=""
    fi
    
    if [ "$color_prompt" = yes ]; then
        PS1='\[\e[0;33m\]\D{%y-%m-%d} \[\e[1;33m\]\D{%T} ${debian_chroot:+($debian_chroot)}\[\e[1;32m\]\u@\h\[\e[0m\]$MODEL:\[\e[1;34m\$
    else
        PS1='\D{%y-%m-%d %T} ${debian_chroot:+($debian_chroot)}\u@\h$MODEL:\w\$ '
    fi
    • [^] # Re: Résolu !

      Posté par  . Évalué à 5. Dernière modification le 11/01/21 à 00:40.

      Une troisième, sans utiliser ni sed, ni awk, ni cut, ni cat, ni tr, ni aucune autre commande externe,
      mais seulement avec des commandes internes de l'interpréteur bash :

      myReg='Raspberry ([^ ]*) ([^ ]*) Model ([^ ]*)'
      [[ $(< model) =~ $myReg ]]
      modele="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
      
      
      • [^] # Re: Résolu !

        Posté par  . Évalué à 4. Dernière modification le 11/01/21 à 00:52.

        Zut, je n'avais pas spécifié le chemin du fichier /proc/device-tree/model
        et il est trop tard pour modifier mon précédent message.

        myReg='Raspberry ([^ ]*) ([^ ]*) Model ([^ ]*)'
        [[ $(< /proc/device-tree/model) =~ $myReg ]]
        modele="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
    • [^] # Re: Résolu !

      Posté par  . Évalué à 3. Dernière modification le 11/01/21 à 11:37.

      le sed 's/Raspberry//;s/Model//;s/Rev.*//;s/ //g' < /proc/device-tree/model peut être remplacé par sed -r -r 's/(Raspberry|Model|Rev.*$| )//g' /proc/device-tree/model

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

    • [^] # Re: Résolu !

      Posté par  . Évalué à 1. Dernière modification le 11/01/21 à 17:18.

      @ cyberjunkie

      Dans tes lignes de commande,
      Il te faudra remplacer la ligne :

          PS1='\[\e[0;33m\]\D{%y-%m-%d} \[\e[1;33m\]\D{%T} ${debian_chroot:+($debian_chroot)}\[\e[1;32m\]\u@\h\[\e[0m\]$MODEL:\[\e[1;34m\$

      par :

          PS1='\[\e[0;33m\]\D{%y-%m-%d} \[\e[1;33m\]\D{%T} ${debian_chroot:+($debian_chroot)}\[\e[1;32m\]\u@\h\[\e[0m\]$MODEL:\[\e[1;34m\$ '
      • [^] # Re: Résolu !

        Posté par  . Évalué à 1.

        Bien vu la cotte fermante qui manque !

        Mais c'était juste un copier/coller foireux de ma part: j'ai vérifié dans mon .bashrc et elle y est ;-)

  • # autre solution

    Posté par  . Évalué à 4.

    mettre le modele dans le hostname

    tu as alors le nom de la machine qui est explicite et indépendant du shell

    pignut-3B
    pingu-2b+
    etc-4b

    :p

    • [^] # Re: autre solution

      Posté par  . Évalué à 1.

      Oui, sauf que non.
      Imaginons que je commence un nouveau projet, de domotique disons.
      Je choisis un nom pour le projet et pour la machine qui le fera tourner 'en prod' : pikachu par exemple.
      Je sais que ma prod tournera sur un RasPi 1B parce que, au niveau de la consommation électrique et de la puissance CPU ça fera bien le boulot.
      Par contre, ma machine 'de dev' sera un Raspi 3B+ parce que je n'ai pas forcément envie de subir les lenteurs du 1B.
      Une fois mon développement terminé, je sauvegarde ma SD puis je la transfère du 3B+ au 1B qui conserve donc le même hostname.
      Si je m’aperçois par la suite que pour une raison lambda j'ai besoin de remplacer le 1B par un 2B ou un Zero, même manip, je transfère juste la SD d'une machine à l'autre, en conservant donc à l'identique toute la partie soft.

      À force, ben je ne sais plus forcément qui fait quoi.
      Ça m'a embêté récemment pour un projet qui nécessitait que je connecte un Pi en bluetooth à un détecteur de radon situé par trop loin.
      Si j'avais eu un joli prompt comme ça à ce moment là, ça m'aurait évité de me prendre la tête à essayer de faire fonctionner du bluetooth sur un Raspi 2B qui n'en est pas équipé!

  • # Une solution sans intervention sur les clients

    Posté par  . Évalué à 2.

    Une autre possibilité est l'ajout d'une commande à ssh:

    ssh -t raspberry 'command; bash -l'

    Par exemple:

    ssh -t raspberry 'cat /proc/device-tree/model | cut -d " " -f 2,3,5; exec bash -l'

    ou remplacer cut par sed comme dans un autre commentaire:

    sed "s/Raspberry//;s/Model//;s/Rev.*//;s/ //g

    Et une fonction dans le .bashrc du host pour ne pas avoir à se souvenir de la commande complète.

    function sshpi() {
    ssh -t "$1" 'sed "s/Raspberry//;s/Model//;s/Rev.*//;s/ //g | cut -d " " -f 2,3,5; exec bash -l'
    }

    L'avantage c'est que c'est qu'il n'y pas besoin de modifier les clients, le désavantage c'est que ça n'apparaît qu'une fois, à la connexion.

  • # Commentaire supprimé

    Posté par  . Évalué à 1. Dernière modification le 14/01/21 à 08:55.

    Ce commentaire a été supprimé par l’équipe de modération.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.