Forum Programmation.shell Ligne de code qui refuse d'être factorisée

Posté par  . Licence CC By‑SA.
Étiquettes :
1
17
nov.
2023

Bonjour à tous les pro du shell… et du bash en particulier,

J'ai écrit un script générant une chaîne de caractères de longueur et complexité variable selon les besoins, histoire de faciliter la génération de login/password pour les services accessibles sur Internet.

J'ai voulu factoriser les sections redondantes pour avoir une meilleure lisibilité et simplifier d'éventuels changements futurs et je fais face à une difficulté.

Initialement, la ligne à factoriser dans une fonction ressemblait à ça :

strings --bytes=1 < /dev/urandom | tr --delete a-z | head --bytes="${LENGHT}" | xargs --null

Pour avoir plus de complexité; je changeais le a-z en azA-Z, A-Z0-9, '[:alnum:]', etc.
Et ça se factorise sans problèmes dans cette fonction :

_get_random()
{
  local char_set
  local symbol

  symbol="$1"
  char_set="$2"

  printf "%s\n" "The generated password is :"
  strings --bytes=1 < /dev/urandom | tr --delete --complement "${symbol}" | head --bytes="${LENGHT}" | xargs --null
  printf "%s\n" "The password entropy is : $(_entropy ${char_set}) bits."
}

Et ça s'utilise avec par exemple :

_get_random a-z 26

Le soucis est avec cette ligne qui génère les chaînes les plus complexes :

strings --bytes=1 < /dev/urandom | tr --delete '[:space:]' | head --bytes="${LENGHT}" | xargs --null

Curieusement le '[:space:]' ne passe pas alors que le '[:alnum:]' passe comme une lettre à la poste.

Selon vous, d'où vient mon erreur ?

PS : j'ai du mal avec la mise en page du code, il y a le ${symbol} qui a merdé.

  • # Question XY ?

    Posté par  . Évalué à 3.

    J'ai écrit un script générant une chaîne de caractères de longueur et complexité variable selon les besoins, histoire de faciliter la génération de login/password pour les services accessibles sur Internet.

    Première question : tu ne peux pas utiliser la commande pwgen ?

    PS : j'ai du mal avec la mise en page du code, il y a le ${symbol} qui a merdé.

    Le code se met dans un bloc encadré par ```. N'hésite pas à utiliser l'aide-mémoire Markdown qui s'affiche en-dessous de la fenêtre de rédaction.

    • [^] # Re: Question XY ?

      Posté par  . Évalué à 1.

      tu ne peux pas utiliser la commande pwgen ?

      Je ne connaissais pas cette commande.
      Elle n'est pas installée sur ma machine…

      Le code se met dans un bloc encadré par ```

      J'avais vu mais ça ne marche pas :-(

      • [^] # Re: Question XY ?

        Posté par  . Évalué à 2.

        Je ne connaissais pas cette commande. Elle n'est pas installée sur ma machine…

        Essaie de l'installer, elle sera probablement dans le paquet pwgen. Sous Debian ou dérivés (comme Ubuntu), ça devrait être sudo apt install pwgen, sous Fedora, sudo dnf install pwgen, …

        J'avais vu mais ça ne marche pas :-(

        PourMoiÇaMarche® ¯_(ツ)_/¯

        _get_random()
        {
        local char_set
        local symbol
        
        symbol="$1"
        char_set="$2"
        
        printf "%s\n" "The generated password is :"
        strings --bytes=1 < /dev/urandom | tr --delete --complement "{$symbol}" | head --bytes="{LENGHT}" | xargs --null
        printf "%s\n" "The password entropy is : (_entropy{char_set}) bits."
        }
        
        • [^] # Re: Question XY ?

          Posté par  (site web personnel) . Évalué à 3.

          Merci pour tes efforts de reformatage mais attention :

          • ${symbol} (permutation des deux premiers caractères) ;
          • ${LENGHT} (manque le dollar) — dont ça n'est pas l'orthographe au passage.

          Je ne comprends pas le problème de gzgtrhe :

          1. Que signifie « ne passe pas » ?
          2. Le code en dehors de la fonction utilise tr --delete, le code dans la fonction utilise tr --delete --complement.

          Alors oui, si on passe en paramètre [:space:], on demande à supprimer tout ce qui n'est pas espace, et il reste des espaces. Et retour au premier point.

          Debian Consultant @ DEBAMAX

          • [^] # Re: Question XY ?

            Posté par  . Évalué à 2.

            Le code en dehors de la fonction utilise tr --delete, le code dans la fonction utilise tr --delete --complement.

            C'était tellement évident que je suis passé à côté.
            Merci !

    • [^] # Re: Question XY ?

      Posté par  (Mastodon) . Évalué à 3.

      J'ai reformaté le journal pour plus de lisibilité.

      Le code se met dans un bloc encadré par ```

      Pour rappel :

      • il faut sauter une ligne pour que ce soit reconnu
      • on peut même donner un langage afin d'avoir la coloration :

      ```bash
      echo "toto"
      ```

      donnera :

      echo "toto"

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: Question XY ?

      Posté par  . Évalué à 4.

      J'ajoute que si tu utilises un gestionnaire de mots de passes (keepassxc, bitwarden…), il y a des générateurs intégrés assez pratiques. Et si tu as plein de mots de passes, je t'encourage à t'y mettre :).

      Ceci dit ça ne fait jamais de mal de faire un peu de shell.

      • [^] # Re: Question XY ?

        Posté par  (site web personnel) . Évalué à -2.

        Ceci dit ça ne fait jamais de mal de faire un peu de shell.

        C'est vraiment très faux.

        pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

        • [^] # Re: Question XY ?

          Posté par  . Évalué à 2.

          Comme toutes les généralités, d'ailleurs. (attention, boucle infinie :D)

        • [^] # Re: Question XY ?

          Posté par  (site web personnel) . Évalué à 5.

          Deux salles deux ambiances

          Il existe deux types d’informaticien·ne·s : celleux qui utilisent la ligne de commande et celleux qui sont à la retraite. Même les développeurs qui adoptent des interfaces de développement très intégrées disposent d’une sorte de terminal dans certains panneaux de leur IDE. Qu’on le veuille ou non, l’interpréteur de commandes fait partie intégrante de la vie quotidienne de la plupart des personnes qui attendent de leur ordinateur qu’il travaille pour elles.

          (source https://linuxfr.org/news/comparaison-critique-de-systemes-d-invite-de-commande )

          • [^] # Re: Question XY ?

            Posté par  . Évalué à 3.

            Si la ligne de commandes et le shell ne servait à rien, Microsoft n'aurait pas inventé Powershell.

            Comme toujours, utiliser l'outil adapté au besoin. Il y a des cas ou un bon vieux script shelle suffira à couvrir un besoin - là ou d'autres, ne connaissant pas l'outil, viendront à utiliser du python ou autre langage, qui constituera une brique nécessitant d'être suivie en terme d'obsolescence, alors que le script shell avec commandes de base en général n'a pas à bouger et sera mis à jour avec le système de base.

            • [^] # Re: Question XY ?

              Posté par  . Évalué à 4.

              En l’occurrence, je crois que l'idée était de dire que faire un générateur de mots de passe avec - en gros - un cat /etc/urandom, c'est une idée assez moyenne. pwgen part de la même source mais diversifie un peu.

          • [^] # Re: Question XY ?

            Posté par  (site web personnel) . Évalué à 1.

            Y’a une différence entre l’usage de la ligne de commande et faire des scripts en shell. Et dans ce dernier cas, je suis très moyennement convaincu de l’utilité d’une telle compétence dans le monde professionnel.

            Le (ba)sh est un langage vraiment peu lisible et peu flexible. On le voit ici où pour générer des trucs aléatoires on se retrouve à coller des bouts de programme entre eux alors que n’importe quel autre langage tel que Python/Ruby/Perl (brrr) s’en sortira de façon beaucoup plus logique et maintenable. Dans un bon nombre d’équipes le bash n’est compris que par les admin sys et on se retrouve avec des difficultés de transmission de compétence assez rapidement alors que nous sommes dans une époque où on a tendance à favoriser les interactions avec les équipes de développement et les équipes gérant la production.

            Ma règle qui est largement discutable c’est qu’au-delà de 20 lignes en bash le langage est mal choisi. Évidemment il y a des exceptions, quand la principale fonction d’un script est d’exécuter des trucs c’est toujours utile d’avoir des notions en bash.

            • [^] # Re: Question XY ?

              Posté par  . Évalué à 5.

              Dans mon expérience, le scripting shell version bash est le dénominateur commun parmi les adminsys, réseau, devs et powerusers. Parfois on a Python, C C++ en commun, mais bash toujours.

              C'est vrai que dès que ça devient sérieux, le shell devient un choix moyen, mais souvent ça permet de régler un problème simple avec un outil simple et omniprésent.

              • [^] # Re: Question XY ?

                Posté par  (site web personnel) . Évalué à 2.

                outil simple

                Le shell n'est pas un outil simple. La complexité sous jacente fuite de partout.

                pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

                • [^] # Re: Question XY ?

                  Posté par  . Évalué à 4.

                  Le shell n'est pas un outil simple. La complexité sous-jacente fuite de partout.

                  Je pourrais ironiser en disant que oui, ok, n'utilisons que des interrupteurs pour faire basculer des bits. Mais là encore, la présence d'arcs électriques, de rebonds et autres grippages mécaniques en feraient un outil pas simple et immaîtrisable te donneraient raison et me couvriraient de ridicule. Je m'abstiens donc d'essayer de comprendre ce qui serait simple en informatique de nos jours :p.

            • [^] # Re: Question XY ?

              Posté par  . Évalué à 6.

              Contrairement à ce que beaucoup de gens croient, il y a encore beaucoup de monde qui connaît le shell. Et comme je l'ai dit plus haut, un script shell sur une distribution linux écrit il y a 20 ans ne bougera probablement pas, alors qu'un script python écrit il y a 10 ans en python2 aura probablement besoin d'être réécrit/adapté en python3.

              Le manque de compétence de mon point de vue n'est pas un sujet : le shell est une compétence à avoir quand on commence à faire de l'intégration sous Linux. Si tu es dev, que tu utilises déjà un langage pour ton appli et que ton besoin est lié à une application, dans ce cas la question du langage ne se pose pas : écris-le dans le langage de ton appli. Si c'est un besoin plus générique, qui n'est pas lié à une application donnée, la question peut se poser.

              • [^] # Re: Question XY ?

                Posté par  (site web personnel) . Évalué à 3.

                L’ennui c’est l’endroit où tu places la limite entre scripter avec du bash est pertinent et efficace vs il commence à avoir pas mal de logique et sortir le langage de l’appli semble plus malin.

                Mon avis est que beaucoup d’admin-sys vont pousser le curseur trop loin et utiliser le bash à des endroits peu pertinents qui peuvent aller au-delà de la simple intégration avec Linux.

          • [^] # Re: Question XY ?

            Posté par  (site web personnel) . Évalué à 1.

            J'utilise la ligne de commande et ça n'est pas ce que je critique. Ton lien ne semble rien dire quant aux scripts shell. J'ai écrit des scripts shell et pratiquement à chaque fois que ça a dépassé les 10 lignes ("#/bin/bash" et "set -eu" compris) c'était une erreur. J'invite les gens à éviter d'apprendre de mes erreurs en évitant de les reproduire.

            Écrire des scripts shell est généralement une erreur qui cause bien du mal pendant longtemps après.

            pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

            • [^] # Re: Question XY ?

              Posté par  . Évalué à 5.

              j'ai fait de nombreux script bash, parfois usant du awk ou des script sed, et même perl, et ce depuis plus de 10 ans.

              A aucun moment cela ne s'est révélé une erreur. L'un des plus récent c'est un script pour générer une version à partir de origin/main, avec tout ce qui faut (tag, version, compilation…)

              Un autre c'est un script qui va chercher dans un jar le profile spring pour aller chercher les bons fichier de conf pour toper les bonne propriété… bref des enchainement de jar, grep…

              par contre des boulettes parce que je n'avais pas fait de script ouais j'en ai fait pas mal. répéter un enchainement de commande 15 fois, parfois y a des retour a la ligne qui se font au mauvais moment, un mauvais rappel, un mauvais enchainement…

              bref pleins de truc qui facilitent la vie et qui font bien le taf. J'en ai d'autre sous wsl pour gérer les mods pour un skyrim ou fallout4, et compiler les scripts… Bref des trucs simple qui seraient super galère à faire autrement.

              En plus l'exemple donné sur rm -rf */ est foireux, la racine ne peut être détruite et donc un rm -rf / ne fait rien ;P du moins en ext2-3-4, je ne sais pas pour les autres systèmes de fichiers

              Similar problems can transform cp and mv into dangerous weapons, and misuse of the > redirect can delete the contents of a file. This is made more problematic by the fact that many UNIX commands differ in name by only one letter: cp, cd, dd, df, etc.

              et ? un bon bashrc file les alias de protection mv => mv -i, cp => cp -i, rm => rm -i, dd a une syntaxe tellement spécifique que le mélange avec les autres ne fera rien…

              Another significant disadvantage is the slow execution speed and the need to launch a new process for almost every shell command executed.

              c'est vrai, mais je ne fait pas tourner un serveur web en bash… bref je ne cherche pas la performance. (et encore… c'est plus rapide d'utiliser mes scripts pour compliler les script skyrim que lancer le creation kit pour faire la même chose…

              There are also compatibility problems between different platforms. Larry Wall, creator of Perl, famously wrote that "It's easier to port a shell than a shell script."[11]

              c'est de moins en moins vrai.

              Bref ces reproches dans wikipedia, c'est surtout si tu cherches à faire une application complexe, et on sort du domaine de script (même si on utilise un langage de script)

              Il ne faut pas décorner les boeufs avant d'avoir semé le vent

              • [^] # Re: Question XY ?

                Posté par  . Évalué à 3.

                j'ai fait de nombreux script bash, parfois usant du awk ou des script sed, et même perl, et ce depuis plus de 10 ans.

                Idem pour moi, depuis 1997, mais he ne me suius pas restreint à bash (j'ai aussi fait du ksh et du sh ).

                A aucun moment cela ne s'est révélé une erreur.

                Je ne pense pas non plus que de mon côté, tout ce que j'ai fait en script shell ait été une erreur (au moins à l'époque ou je l'ai fait et avec les moyens que j'avais). Par contre, sans parler d'erreur, pour certaines choses que j'ai faites à mes débuts (par exemple un système de gestion de sauvegardes sur un robot de 6 bandes, avec des scripts lancés sur les machines à sauvegarder depuis un serveur central, sans outil de sauvegarde du commerce parce que ça coutait trop cher, tout écrit en script ksh), je n'utiliserai plus forcément des scripts shell mais je passerais peut-être plutôt par un langage tel que python (enfin, je me poserais la question).

                un bon bashrc file les alias de protection mv => mv -i, cp => cp -i, rm => rm -i,

                Ca ne changera rien si tu fais ça dans un script … car le but d'un script est justement de ne pas ajouter d'interactivité. Mais ce genre de problème (effacer le mauvais fichier) n'est pas propre au shell : il est possible de le faire dans n'importe quel langage !!!

                c'est vrai, mais je ne fait pas tourner un serveur web en bash…

                Moi non plus …. Celà dit, un script shell couplé à un inetd bien senti pourrait le permettre je pense non  ? :)

                Bref ces reproches dans wikipedia, c'est surtout si tu cherches à faire une application complexe, et on sort du domaine de script (même si on utilise un langage de script)

                Comme d'habitude : utiliser l'outil adapté au besoin.

      • [^] # Re: Question XY ?

        Posté par  . Évalué à 2. Dernière modification le 18 novembre 2023 à 18:50.

        si tu utilises un gestionnaire de mots de passes (keepassxc, bitwarden…)

        J'ai découvert KeepassXC plus tard… et je l'utilise depuis :-)

Suivre le flux des commentaires

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