Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème bash inutile mais j'aimerais comprendre

Sujet résolu
    9 décembre 2022 à 18:03:45

    Ce matin je faisais mumuse avec rolldice et puis je sais pas trop pourquoi j'ai eu l'idée d'utiliser le résultat de rolldice pour créer une variable ayant une probabilité voulu dans un script.
    Oui je sais c'est pas l'idée du siècle mais j'aime bien essayer tout ce qui me passe par la tête.
    Alors j'ai écrit ça pour essayer voir si ça marche (le script en lui-même il sert à rien, sinon d'identifier le problème, ou de jouer au dés tout seul contre son ordinateur, ce qui n'est pas très glorieux j'avoue aahaha)
    #!/bin/bash
    
    var1= rolldice "1d6"   
    var2= rolldice "1d6" 
    echo " $var1 " 	#renvoi ligne vide, ça m'a permis de comprendre le problème mais j'ai pas la solution 
    if [ "$var2" -gt "$var1" ] ; then
      echo "succès"               
    else
      echo "perdu"                         
    fi

    Le prompt renvoi ça:
    chaos@fleaux:~/Documents/scripts$ ./test-rolldice.sh 
    6 
    1 
      
    ./test-rolldice.sh: ligne 6 : [:  : nombre entier attendu comme expression
    perdu
    

    Alors je pense avoir identifié le problème, le résultat de rolldice 1d6 même s’il apparait au prompt comme un nombre entier en fait le résultat en lui même n’est pas un nombre entier mais un morceau de code qui fait apparaitre au prompt le nombre entier.
    Du coup ça fait à peu près 8h que je me casse la tête à essayer de récupérer ce nombre entier pour en faire la variable. (Oui oui j’ai rien d’autre à foutre je sais xd)

    Je pense que ça doit être faisable avec grep mais j’arrive pas à trouver dans quel fichier rolldice écrit la réponse.

    Si jamais quelqu’un a une idée je suis preneur.

    Vous foutez pas trop de ma gueule ça fait 10 ans que j’ai pas écrit une ligne de bash alors mes souvenirs commencent à être un peu poussiéreux. Déjà que j’avais pas un super niveau alors là bonjour la catastrophe! Enfin du coup c'est un peu l'objectif aussi, bidouiller et trouver des solutions aux problèmes rencontrés histoire de capter comment ça marche quoi.

    Merci d'avance si quelqu'un prend le temps de me répondre.

    (Je poste ça ici parce que je sais pas trop dans quelle catégorie le mettre)

    EDIT: Bon ben c'était juste une erreur de syntaxe en fait oups!
    9h pour m'en rendre compte haahaha.
    Désolé du topik qui sert à rien
    Je passe en résolu

    #!/bin/bash
    
    var1=$(rolldice "1d6")   
    var2=$(rolldice "1d6") 
    echo "$var1" 	#maintenant ça fonctionne
    if [ "$var1" -gt "$var2" ] ; then
      echo "succès"               
    else
      echo 

    -
    Edité par A-Chaos 9 décembre 2022 à 19:27:10

    • Partager sur Facebook
    • Partager sur Twitter
      9 décembre 2022 à 23:47:21

      #!/bin/bash
       
      declare -i var1=$(rolldice "1d6")  var2=$(rolldice "1d6")
      
      (($var1 <= 0)) || { >&2 echo "le premier tirage ne peut pas être inférieur ou égal à 0 (\$var1 = $var1); je quitte."; exit 1;}
      (($var2 <= 0)) || { >&2 echo "le second tirage ne peut pas être inférieur ou égal à 0 (\$var2 = $var2); je quitte."; exit 1;}
      
      (( $var1 > $var2 )) && echo "succès" ||  echo "échec"
      

      ou, si tu as besoin de faire plus qu'un simple affichage :

      if (( $var1 > $var2 ))
      then
        echo "succès"              
      else
        echo "échec"
      fi
      

      -
      Edité par dantonq 9 décembre 2022 à 23:49:33

      • Partager sur Facebook
      • Partager sur Twitter

      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

        10 décembre 2022 à 0:13:52

        Cool merci beaucoup pour la solution avec declare, j'avais essayé mais ça marchait pas du coup j'ai pas creusé. (mais bon normal que rien ne marchait à cause de la syntaxe xd)


        Au final quand j'ai compris ma connerie j'ai fait le script suivant parce que le problème existe toujours avec roll par contre (j'avais commencé à tester avec roll et c'est pour ça que je suis resté bloqué sur cette idée d'aller récupérer des caractères dans un fichier parce que roll ne donne pas uniquement le résultat total numérique), du coup la solution est simple, il suffit d’écrire un fichier du résultat de roll et aller chercher les caractères dont on a besoin (en l’occurrence le dernier “mot” de la première ligne qui est le résultat total numérique -j’ai utilisé sed-)

        Et puis au passage j’en ai profité pour nettoyer le premier script bien dégueu .
        Et puis pour utiliser roll non pas comme un lanceur de dés mais comme une probabilité échec/réussite de “n” évènements j’en ai fait un jeu de roulette russe avec choix du nombre de balles à mettre dans le barillet.

        #!/bin/bash
        
        	#test avec rolldice
        var1=$(rolldice "1d6")   
        var2=$(rolldice "1d6") 
        echo -e "Test avec rolldice \nTu fais $var1 \nil fait $var2"	#C'est plus propre comme ça quand même
        test "$var1" -gt "$var2" && echo -e "succès\n" || echo -e "perdu\n"
        
        	#test avec roll
        roll '1d6' > tempVar1.txt && roll '1d6' > tempVar2.txt		#Création des fichiers
        var3=$(sed -n 1p tempVar1.txt | sed 's/.* //')			#Création des variables en ne récuppérant uniquement les caractères voulus
        var4=$(sed -n 1p tempVar2.txt | sed 's/.* //')
        echo -e "Test avec roll \nTu fais $var3 \nIl fait $var4"
        test "$var3" -gt "$var4" && echo -e "succès\n" || echo -e "perdu\n"
        rm tempVar1.txt tempVar2.txt					#Suppression des fichiers
        
        
        	#test avec roll 4d264
        roll '4d264' > tempVar1.txt && roll '4d264' > tempVar2.txt
        var3=$(sed -n 1p tempVar1.txt | sed 's/.* //')			
        var4=$(sed -n 1p tempVar2.txt | sed 's/.* //')
        echo -e "Test avec roll 4d264 \nTu fais $var3 \nIl fait $var4"
        test "$var3" -gt "$var4" && echo -e "succès\n" || echo -e "perdu\n"
        rm tempVar1.txt tempVar2.txt
        
        
        	#roulette russe
        echo -e "ROULETTE RUSSE\nPour utiliser la probabilité échec/réussite d'un évennement\n"
        read -p "dans un barillet à 6 balles tu veux en mettre combien? :  " var1
        sleep 1
        var2="1d$((6 / $var1))" 
        var3=$(rolldice "$var2") 
        test "$var3" -eq 1 && echo -e "T'es mort\n" || echo -e "T'es encore vivant\n"
        
        exit

        Donne:

        chaos@fleaux:~/Documents/scripts$ ./test-rolldice.sh 
        Test avec rolldice 
        Tu fais 5  
        il fait 4 
        succès
        
        Test avec roll 
        Tu fais 5 
        Il fait 3
        succès
        
        Test avec roll 4d264 
        Tu fais 617 
        Il fait 636
        perdu
        
        ROULETTE RUSSE
        Pour utiliser la probabilité échec/réussite d'un évennement
        
        dans un barillet à 6 balles tu veux en mettre combien? :  2
        T'es mort
        


        Demain j'essaie de tout refaire avec declare pour voir. J'ai essayé awk à la place de sed aussi mais j'y suis pas arrivé. Merki pour le conseil !


        • Partager sur Facebook
        • Partager sur Twitter
          10 décembre 2022 à 0:27:33

          je ne trouve pas roll dans les dépôts.
          quelle distribution utilises-tu ?
          • Partager sur Facebook
          • Partager sur Twitter

          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

            10 décembre 2022 à 3:20:21

            Ubuntu en ce moment mais c'est parce que c'est un paquet snap :

            $ snap info roll
            name:      roll
            summary:   A python dice rolling application using standard dice notation
            publisher: Sikander (metasikander)
            store-url: https://snapcraft.io/roll
            contact:   sikander@lhote.me
            license:   unset
            description: |
              Syntax is: roll <dice_code>
              Example: roll 2d8 + 6 + d8
              Instead of a dice code you can also put "stats" or "dir" for a stats roll
              or direction roll respectively.
            commands:
              - roll
            snap-id:      IvnCzCWzRtru2wmQr3uSWC7kQ6rMXODi
            tracking:     latest/stable
            refresh-date: hier à 06 h 34 HNR
            channels:
              latest/stable:    1.9 2019-02-06 (1) 9MB -
              latest/candidate: 1.9 2019-02-06 (1) 9MB -
              latest/beta:      ↑                      
              latest/edge:      ↑                      
            installed:          1.9            (1) 9MB -
            



            J'avais zappé désolé.

            Édit: Différence entre les deux sur le résultat:

            ~$ rolldice 4d22
            54 
            ~$ roll 4d22
            Total: 19
            Rolls: ['7/22', '2/22', '7/22', '3/22']
            



            -
            Edité par A-Chaos 10 décembre 2022 à 3:45:28

            • Partager sur Facebook
            • Partager sur Twitter
              10 décembre 2022 à 11:54:26

              je n'ai pas d'Ubuntu physique, et snap ne peut pas fonctionner, mais ce n'est pas très important, finalement.

              si le retour de roll est ce que tu montres :

              Total: 19
              Rolls: ['7/22', '2/22', '7/22', '3/22']

              en faisant ainsi

              read dum val < <(roll 4d22)

              alors

              echo $val

              doit afficher

              19

              -
              Edité par dantonq 10 décembre 2022 à 11:55:03

              • Partager sur Facebook
              • Partager sur Twitter

              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                10 décembre 2022 à 15:23:09

                dantonq a écrit:

                #!/bin/bash
                 
                declare -i var1=$(rolldice "1d6")  var2=$(rolldice "1d6")
                
                (($var1 <= 0)) || { >&2 echo "le premier tirage ne peut pas être inférieur ou égal à 0 (\$var1 = $var1); je quitte."; exit 1;}
                (($var2 <= 0)) || { >&2 echo "le second tirage ne peut pas être inférieur ou égal à 0 (\$var2 = $var2); je quitte."; exit 1;}
                
                (( $var1 > $var2 )) && echo "succès" ||  echo "échec"
                

                Ne fonctionne pas, j'ai patiné longtemps à comprendre pourquoi! Pour éliminer les possibilités j'ai écris une ligne en plus pour vérifier que DECLARE renvoie bien des valeurs positive, ensuite j'ai inversé <= pour voir, toujours le message d'erreur. J'ai essayé avec TEST avant de percuter que c'est une boucle du coup j'ai fini par utiliser la syntaxe [  -gt  ] en remplaçant 0 par 1 puisque de toute façon DECLARE ne renvois qu'un entier donc strictement inférieur à 1 ou inférieur ou égal à 0 c'est la même chose. L'autre solution aurait été de supprimer ces deux lignes parce que de toute façon ROLLDICE ne peut pas renvoyer de valeur négative mais je voulais comprendre pourquoi ça redirigeait toujours vers un message d'erreur.
                Je l'ai modifié comme ça: (j'espère que c'est correct)

                #!/bin/bash
                
                declare -i var1=$(rolldice "1d6")  var2=$(rolldice "1d6")
                echo -e "Tu fais $var1\nIl fait $var2"
                [ $var1 -gt 1 ] || { >&1 echo "le premier tirage ne peut pas être inférieur ou égal à 0 (\$var1 = $var1); je quitte."; exit 1;}
                [ $var2 -gt 1 ] || { >&1 echo "le second tirage ne peut pas être inférieur ou égal à 0 (\$var2 = $var2); je quitte."; exit 1;}
                
                (( $var1 > $var2 )) && echo "succès" ||  echo "échec"

                Pour ROLL:

                1
                	
                read dum val < <(roll 4d22)



                Marche très bien mais je n'arrive pas à comprendre

                dum val < <(roll 4d22)

                Je cherche un peu partout pour retrouver un équivalent histoire de comprendre ce que DUM  et la syntaxe < <(...) fait exactement pour pouvoir l'adapter à une autre situation mais je trouve nulle part.

                Merci beaucoup pour les réponses en tout cas.

                -
                Edité par A-Chaos 10 décembre 2022 à 16:04:20

                • Partager sur Facebook
                • Partager sur Twitter
                  10 décembre 2022 à 20:05:20

                  @A-Chaos Bonsoir, je viens de sortir des spams votre dernier message, si cela ce reproduit vous pouvez poster dans ce sujet Si votre message est considéré comme spam

                  Merci de ne pas répondre dans une citation mais après, sinon on ne sais plus qui dit quoi.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 décembre 2022 à 20:34:43

                    ensuite j'ai inversé <= pour voir, toujours le message d'erreur.

                    quel est le message ?

                    dum (dummy) est un nom de variable arbitraire/bidon, parce qu'on ne s'en servira pas; ça consomme le premier mot (au sens shell du terme : tous les caractères jusqu'à un délimiteur de l'IFS (par défaut : espace, tabulation, alinéa)).

                    en shell, par défaut, les variables ne sont pas typées; declare -i attribue le type entier (positif ou négatif) à une variable.

                    <(...) est une Substitution de processus (cf. man bash).
                    ça permet de faire lire le résultat d'une commande comme s'il s'agissait d'un fichier

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                      13 décembre 2022 à 11:01:46

                       En fait il y avait juste une erreur, ça fonctionne avec

                      (($var >= 0 ))

                      Pas l'inverse, en cherchant je pense avoir compris que la syntaxe dit "si l'expression renvoi 0" autrement dit si elle est fausse, alors {... Sinon, la suite...

                      Ok donc comme DECLARE type la variable ce n'est pas utile d'utiliser -gt comme comparateur si j'ai bien compris
                      (Il y avait juste un espace en fin de ligne que je n'avais pas vu quand j'ai copié collé ton code, du coup quand je l'ai écris sans copier ça a fonctionné nickel, enfin juste en inversant le comparateur)

                      Merci beaucoup pour les explications, concernant DUM et la substitution de processus je vais noter ça quelque part, j'avais cherché sur le manuel de bash oui et je me doutais bien que c'était quelque part mais c'était pas évident à trouver haahaha.

                      Désolé pour le double post, je n'avais pas vu la réponse.



                      -
                      Edité par A-Chaos 13 décembre 2022 à 11:06:44

                      • Partager sur Facebook
                      • Partager sur Twitter
                        13 décembre 2022 à 12:08:57

                        typer une variable permet de s'assurer qu'elle contiendra un nombre, même si on lui assigne du texte.
                        ça n'a pas d'influence sur le choix de l'évaluation.

                        $ declare -i var
                        $ var="foo bar"
                        $ echo $var
                        0

                        c'est un choix personnel, je préfère une évaluation arithmétique plutôt qu'un test pour comparer des nombres.
                        je sais immédiatement visuellement de quoi il s'agit : nombre ou texte.
                        l'évaluation arithmétique offre aussi plus de possibilités qu'un simple test

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                          14 décembre 2022 à 20:58:37

                          Oki, merci, du coup si ça ne change rien je trouve plus évident d'utiliser l'évaluation arithmétique en effet.
                          J'ai une autre question, ça fait un moment que je cherche mais je trouve pas. Bon à la base l'idée c'était de travailler sur les probas. Lorsque l'on complique une équation de jeté de dés si on veut calculer la probabilité d'un résultat mathématiquement en utilisant la loi binomiale ça devient vite l'enfer... Par contre un script doit être capable de le faire beaucoup plus simplement. Il suffit de comptabiliser tous les résultats de toutes les combinaisons possibles et de comptabiliser toutes les fois où l'on obtient le résultat duquel on veut la proba, on divise le second par le premier et forcément on a la proba de l'évènement.
                          Du coup je me suis créé un problème simple pour commencer:

                          	#Soit l'expression roll 2d20/1d10 = 1.25
                          	#Quelle est la probabilité d'obtenir 1.25
                          	
                          	#valeurs possibles 2d10: nombre entier compris entre [2;40]
                          	#valeurs possibles 1d20: nombre entier compris entre [1;10]
                          	
                          echo -e "Je lance 2 dés de 20 faces puis je divise le résultat obtenu par le lancé d'un dés de 10 faces, quelle est la probabilité d'obtenir un résultat de 1.25 \n"
                          
                          for var1 in {2..40..1};
                          do for var2 in {1..10..1}; do echo $var1/$var2 |bc -l >> op.tmp
                          	done; done
                          	
                          var3=$(wc -l op.tmp | sed -e 's/[^0-9]//g')	#nbre lignes du fichier (nbre résultats possibles)
                          echo "Nombre de possibilités totale: $var3 "
                          var4=$(grep 1.25 op.tmp | wc -l)	#nbre résultats positif (1.25)
                          echo -e "Nombre de possibilités d'obtenir 1.25 : $var4 \n"
                          echo -e "Probabilité d'obtenir 1.25 (unité %): $($var4/$var3*100 |bc -l) "
                          
                          rm op.tmp




                          Problème sur l'avant dernière ligne renvoie:
                          $ ./proba-roll.sh 
                          Je lance 2 dés de 20 faces puis je divise le résultat obtenu par le lancé d'un dés de 10 faces, quelle est la probabilité d'obtenir un résultat de 1.25 
                          
                          Nombre de possibilités totale: 390 
                          Nombre de possibilités d'obtenir 1.25 : 2 
                          
                          Probabilité d'obtenir 1.25 (unité %): &(2/390*100 |bc -l) 
                          


                          J'ai essayé de l'écrire de plein de façons différentes mais la seule qui fonctionne c'est:

                          echo -e "Probabilité d'obtenir 1.25 (unité %): " && echo $var4/$var3*100 |bc -l

                          Qui renvoi

                          Probabilité d'obtenir 1.25 (unité %): 
                          .51282051282051282000
                          
                          Alors bon ça fonctionne mais je trouve que c'est pas jolie et puis je me demandais si on est vraiment obligé de l'écrire en deux fois? J'aimerais bien que ce soit le plus clean possible parce qu'après j'ai envie d'essayer de compliquer le truc en donnant le choix du nombre de faces et du nombres de lancés de dés. Le top ça serait carrément de donner le choix sur l'équation de départ mais ça j'y crois pas trop.

                          -
                          Edité par A-Chaos 14 décembre 2022 à 21:02:32

                          • Partager sur Facebook
                          • Partager sur Twitter
                            14 décembre 2022 à 21:44:21

                            ligne 17 :  tu ne fais pas d'echo dans la Substitution de commandes.

                            #!/bin/bash
                            
                            LC_NUMERIC=C # pour printf
                            
                            echo -e "Je lance 2 dés de 20 faces
                            puis je divise le résultat obtenu par le lancé d'un dé de 10 faces.
                            Quelle est la probabilité d'obtenir un résultat de 1.25 \n"
                             
                            bc -l <<<'for(d20=2;d20<=40;d20++) for(d10=1;d10<=10;d10++) d20/d10' >op.tmp
                                 
                            #nbre lignes du fichier (nbre résultats possibles)
                            #var3=$(wc -l < op.tmp)
                            var3=$(( (40-1)*10 )) #(40 faces moins une) calculées 10 fois -> 390 
                            #nbre résultats positif (1.25)
                            var4=$(grep -c 1.25 op.tmp)
                            
                            echo "Nombre de possibilités totale: $var3"
                            printf 'Nombre de possibilités d'\''obtenir %.2f : %d\n\n' 1.25 $var4
                            printf 'Probabilité d'\''obtenir %.2f (unité %%) : %f\n' 1.25 $(bc -l lt;<<"$var4/$var3*100")
                             
                            rm op.tmp
                            
                            • fais attention à l'indentation
                            • pense à donner des noms de variables représentatifs de ce qu'elles contiennent aux variables

                            PS : un dé à vingt faces n'est-il pas numéroté de 1 à 20 ? alors, pourquoi la boucle d'énumération commence-t-elle à 2 ?

                            -
                            Edité par dantonq 14 décembre 2022 à 23:42:05

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                              15 décembre 2022 à 0:26:30

                              Ah oui comme ça c'est beaucoup mieux c'est clair! Faut que j'aille potasser PRINTF du coup :)
                              Le FOR est carrément plus intuitif!
                              Merci pour les conseils oui je vais aller bosser ça.


                              Pour ton PS, justement c'est mathématiquement faux et du coup avec ton écriture j'ai trouvé la solution de suite.
                              En fait quand tu lances 2 dés tu ne peux pas avoir 1 en additionnant les résultats, c'est 2 minimum. Cependant ce que j'ai écris est faux car avec 2 dés on se retrouve avec une proba triangulaire alors qu'avec mon écriture on avait une proba linéaire (un peu comme si on lançait un seul dés de 40 faces et qu'on explosait la face 1).
                              Pour retrouver la proba triangulaire il faut faire:

                              (roll 1d20 + roll 1d20) / roll 1d10

                              D'ailleurs c'est exactement ce que fait roll en lançant

                              roll 2d20/1d10


                              Ce qui fait qu'avec ton écriture c'est juste évident, il suffit de modifier comme ceci:

                              bc -l <<<'for(d1=1;d1<=20;d1+=1) for(d2=1;d2<=20;d2+=1) for(d3=1;d3<=10;d3+=1) (d1+d2)/d3' >op.tmp
                              


                              C'était le fond du problème que je n'arrivais pas à résoudre car les probas de lancés de dés (ou d'un évènement ayant 1/n chance d'arriver, n étant le nombre de face c'est pareil) sont variables dans le cas de lancés multiples, pour 1 dé c'est une proba linéaire, pour 2 dés une proba triangulaire et à partir de 3 dés il existe une fonction pour la calculer.
                              Le problème c'est qu'on ne peut pas combiner les 3 types de probas ensemble avec une fonction mathématique qui marcherait tout le temps. C'est pour ça que calculer la proba d'un évènement qui dépend lui-même de sous évènements c'est l'enfer. Alors qu'avec un script en imbriquant des FOR comme ça ça se fait tout seul.

                              Edit: Par contre pour que ça fonctionne il faudra conserver:

                              var3=$(wc -l < op.tmp)



                              -
                              Edité par A-Chaos 15 décembre 2022 à 0:33:48

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Problème bash inutile mais j'aimerais comprendre

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown