Journal Batsh - Scripting Bash, et Windows

Posté par  .
Étiquettes :
18
18
mar.
2015

Vous avez a écrire des scripts bash, et des fichiers batch (pour Windows) et vous n’aimez pas l’un ou l’autre, voir les deux?
Séchez vos larmes! Voici (peut-être) la solution à vos souffrances!
Batsh
C’est un langage de programmation basé sur le C, dont le compilo est capable de générer des scripts bash, et batch.
La page du projet sur Github
Une demo en ligne
Et un article dans Linux Magazine
A priori il manque encore quelques trucs, mais pour les allergiques à la syntaxe Bash (comme moi), qui n’ont pas de besoins hyper tordus/pointus/turlututu, ça le fait.

  • # Xonsh

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

    Tiens, dans le rayon des projets avec un nom bizare, j'ai vu passer xonsh : http://xonsh.org/

    "xonsh is a Python-ish, BASHwards-compatible shell language and command prompt. The language is a superset of Python 3.4 with additional shell primitives that you are used to from BASH and IPython. xonsh is meant for the daily use of experts and novices alike."

    J'ai jeté un oeil et je reste un peu sceptique. Je ne sais pas si ça tourne sous Windows :-p

    • [^] # Re: Xonsh

      Posté par  . Évalué à 2.

      Oui, j'ai vu xonsh recemment mais a mon avis, il manque un mode ´strict' qui t'empeche un conflit entre les variables et les executables.

  • # Umpf ?

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

    basé sur le C, dont le compilo

    Donc rien à voir avec un langage de script.

  • # Syntaxe bash ?

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

    mais pour les allergiques à la syntaxe Bash (comme moi)

    Existe t il quelqu'un qui "sérieusement" aime la syntaxe Bash ?
    Par contre si on éloigne la syntaxe de 2 ou 3 parsecs ça reste un langage de script puissant.

    kentoc'h mervel eget bezan saotred

    • [^] # Re: Syntaxe bash ?

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

      Existe t il quelqu'un qui "sérieusement" aime la syntaxe Bash ?

      Oui, il sévit sous le pseudonyme de Michaël, j'ai lu deux de ses journaux récemment (ici et ), et je dois dire qu'il a un point de vue très intéressant sur Bash, notamment dans ce commentaire.

      • [^] # Re: Syntaxe bash ?

        Posté par  (site web personnel) . Évalué à 5. Dernière modification le 19 mars 2015 à 11:32.

        Je n'ai jamais dis que je n'aimais pas le shell.
        Mais ce coquillage a une carapace dure, tranchante, glissante, du genre tu te blesses rien qu'en la regardant, mais une fois que tu sais t'y prendre l'intérieur est délicieux et savoureux avec un quelque chose de "revient y" très appréciable, ce n'est pas pour rien qu'il y a autant d'ennemis à systemd (:-D).

        kentoc'h mervel eget bezan saotred

    • [^] # Re: Syntaxe bash ?

      Posté par  . Évalué à 3. Dernière modification le 19 mars 2015 à 10:36.

      Ben… l'un des arguments utilisés contre systemd c'est l'abandon du bourne shell. Donc j'imagine que oui. :) (okok il est encore un peu tôt, j'aurai du attendre pour les attirer)

      Toujours est-il que même si je commence à être un peu plus confortable avec ce langage, je remercie vraiment l'inventeur de man, particulièrement quand je me mêle d'utiliser test.
      Mais, ouai, c'est vrai: c'est puissant, et je sais pas ce que je ferai sans non plus.

    • [^] # Re: Syntaxe bash ?

      Posté par  (site web personnel) . Évalué à 5. Dernière modification le 19 mars 2015 à 12:14.

      Je ne vois pas en quoi la syntaxe du shell serait si terrible…

      D'une part accolades, points virgules, mots clés n'ont rien d'exotique, et d'autre part sa syntaxe a, à mon avis, certains avantages indéniables:

      mail $(getmail tonton) < monmail
      troff * | dpost | ps2pdf - > tousmesdocs.pdf

      Tubes, redirections, substitutions de commandes, expressions régulières, ont été inventées pour le shell et les raccourcis symboliques définissent la spécificité de sa syntaxe. Je ne connais pas plus simple.

      De même, l'utilisation d'un symbole pour représenter les variables est une invention de Bourne. L'enjeu est le suivant: en ligne de commande, on ne s'ennuie pas à mettre des guillemets pour représenter chaque chaîne de caractères, parce que celles-ci forment la majorité de ce que l'on tape (noms de fichiers, exécutables). On utilise donc un petit $ pour représenter les variables.

      On peut certainement perfectionner la syntaxe, mais franchement, pour manipuler une hiérarchie de fichiers au moyen d'un ensemble d'exécutables, je ne vois pas de syntaxe plus adaptée.

      • [^] # Re: Syntaxe bash ?

        Posté par  . Évalué à 4. Dernière modification le 19 mars 2015 à 16:30.

        Il y a deux énormes problème en shell : le scoping et les "tableaux".

        Pour passer les arguments à une commande, quelle est la bonne manière : cmd "$*", cmd "$@", cmd $* ou cmd $@ ? (hint : sachant que zsh et bash n’ont pas le même comportement en plus…)

        Et ça c’est encore la version simple. Supposons que tu veuilles passer tous les arguments à une commande, en les remplaçant d’une certaine façon (par exemple en remplaçant les chemins relatifs par des chemins absolus), comment tu fais ? (vraie question hein, le problème s’est posé à moi il y a quelque jour, ben je suis passé à Python après m’être cassé la tête contre le mur pendant quelques heures)

        Les scopes sont très rigolo aussi. Petit jeu : qu’affiche ce programme ?

        zenity --forms --text Configuration --title="Configuration" --add-entry="Login" --add-entry "Mot de passe" | IFS='|' read login pwd
        echo "Hello, $login"

        Réponse : "Hello, ". Le bon programme serait :

        zenity --forms --text Configuration --title="Configuration" --add-entry="Login" --add-entry "Mot de passe" | {
        IFS='|' read login pwd
        echo "Hello, $login"
        }

        Explications : dans certains cas, le shell fork. S’il fork les variables d’environnement ne sortent pas du fils. Ce qui donne des challenge intéressant comme : comment savoir à l’avance dans quelle situation le shell va forker ? (dans le premier exemple, le fork pour read était loin d’être évident…), et surtout, comment réussir à réorganiser tout ton programme pour qu’il ne fork pas parce que tu as besoin de la variable login au bon endroit ? (dans mon exemple j’ai pas réorganisé, j’ai tout fait dans le fils, mais si j’avais eu besoin de login dans le processus initial…)

        Dernier point en shell, il est impossible de choper le code de retour des processus initiaux et intermédiaires dans une chaine de pipes. Ce qui, couplé à des trucs précédents, donne lieu à de grosses grosses prises de tête. Exemple, comment faire pour détecter le cas « téléchargement foiré » dans la chaine suivante ?

        curl http://monsite | sed s/toto/tata > test

        Le shell est un langage qui est extrêmement intéressant et bien pensé par certains aspects, mais il a aussi d’énormes problèmes.

        • [^] # Re: Syntaxe bash ?

          Posté par  . Évalué à 2.

          Dernier point en shell, il est impossible de choper le code de retour des processus initiaux et intermédiaires dans une chaine de pipes.

          Un petit exemple pour la route :

          moi:~$ echo "toto, tata" | grep "tutu" | sed 's=u=a=' 
          moi:~$ echo ${PIPESTATUS[*]}
          0 1 0
          moi:~$ 

          C’est bien ce que tu voudrais faire ?

          • [^] # Re: Syntaxe bash ?

            Posté par  . Évalué à 2.

            Spécifique Bash (et assez moche de surcroît, tu perds la localité que tu as avec la syntaxe a || b)

            • [^] # Re: Syntaxe bash ?

              Posté par  . Évalué à 2.

              Spécifique Bash

              Oui, le titre c’est : « Batsh - Scripting Bash, et Windows ». Mais tu as raison, ta question était plus générale. Il y a une réponse dans la FAQ de comp.unix.shell. Je t’accorde que la version POSIX shell est moche.

              (et assez moche de surcroît,

              Ça, c’est une question de point de vue. Je trouve que l’idée du tableau est plutôt pas mal.

              tu perds la localité que tu as avec la syntaxe a || b)

              Je répondais à : « il est impossible de choper le code de retour des processus initiaux et intermédiaires dans une chaine de pipes. ». Dans ce cas, étant donné que si a répond OK, b ne sera pas exécuté, il ne risque pas d’avoir un code de retour.

        • [^] # Re: Syntaxe bash ?

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

          Supposons que tu veuilles passer tous les arguments à une commande, en les remplaçant d’une certaine façon (par exemple en remplaçant les chemins relatifs par des chemins absolus), comment tu fais ?

          Quelque chose comme suit ne fait-il pas l'affaire ?

          while [ $# -gt 0 ]
          do
              echo /mon/chemin/$1
              shift
          done | xargs echo

          Je réponds à la suite plus tard…

          • [^] # Re: Syntaxe bash ?

            Posté par  . Évalué à 2. Dernière modification le 19 mars 2015 à 18:27.

            Et si tu as un retour chariot dans les arguments ? (git commit -m par exemple)

            Et si tu dois utiliser l’entrée standard de ton process pour autre chose ?

            • [^] # Re: Syntaxe bash ?

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

              D'accord, on peut rajouter plusieurs contraintes, mais enfin, tu changes les règles du jeu là. :)

              Il y a nécessairement des cas où le shell n'est pas adapté, et il y a peut-être même des choses qu'il est incapable de faire. Mais àmha, rien qui justifie les critiques à l'emporte pièce que l'on lit parfois ici.

  • # Je suis sceptique. Très.

    Posté par  . Évalué à 7.

    TL;DR:
    Intéressant. Mais code généré crade et pas portable, ainsi que comportements étranges.

    Si je développe, ça donne ça:

    L'idée de base est intéressante.

    Sauf que, l'un des principaux défauts que je reproche au scripting (en tant que dev C/C++), ce sont les erreurs de syntaxe découvertes au runtime dudit script.
    Hors, rien n'est indiqué dans les liens à ce sujet. J'ai testé ceci:

    if ( "hello" === "world" )
    {
        println("niark");
    }
    

    et ça passe! Ça génère ceci en bash:

    _0="hello"
    _1="world"
    if [ $(($_0 == $_1)) == 1 ]; then
      "echo" "-e" "niark"
    fi

    Le premier truc que je constate, c'est que si j'en avait pas fait exprès de mettre un 3ème '=', je me serai attendu… à ne rien afficher. Erreur de syntaxe, ou juste syntaxe à la con? Si c'est une erreur de syntaxe, alors rien n'aurait du être généré. Si c'est une syntaxe à la con style le === du PHP, alors ça n'aurait pas du rentrer dans l'affichage de niark. Parce que l'on parle d'égalité… Enfin, il check peut-être que le type, ce qui est à mon avis encore pire que la syntaxe PHP… opinion personnelle je suppose.
    Bref, déjà, ce truc fait des choses exotiques, auxquelles un développeur C ou Java risque de ne pas être habitué. Donc, la phrase If you have learned C, Java, C++ or JavaScript, Batsh is quite easy for you. me semble fausse. Ça pue les surprises à plein nez.

    Ensuite, le code généré. Oh, le bel "echo". Pourquoi ne pas avoir utilisé printf en bash, dont le comportement est plus prévisible? Parce que echo ne réagit pas de la même façon sur tous les systèmes à ce que j'ai cru comprendre(2nde réponse).
    Toujours au sujet de cette ligne: sur 5 lignes, ça va, mais sur un script un peu compliqué, la maintenance (genre débogage) je la sens pas: pourquoi foutre des " partout?

    Passons à l'argumentaire de l'auteur sur le pourquoi utiliser ce truc. Y'a un truc qui m'a gêné, ça:

    Why not Python/Ruby/Node.js/Lua
    None of them is preinstalled on all platforms (including Windows).

    Ben, bash n'est pas installé sur tous les UNIX. Le SH, oui, le BASH non. Quand je programme, il me faut une bonne raison pour faire un truc qui risque d'être utilisé ailleurs pas portable. Pire, vu que les gens de Debian ont mis dash en interpréteur par défaut dans plusieurs cas, ça veut dire que les scripts générés par ce truc ne marcheront pas.
    Sans même parler de la pratique élémentaire de mettre un shebang en début de fichier…

    Bref: très très sceptique. Voire, pas pour moi.

    • [^] # printf

      Posté par  . Évalué à 2.

      Pourquoi ne pas avoir utilisé printf en bash, dont le comportement est plus prévisible?

      Tant qu’on n’utilise que bash, le comportement d’echo est prévisible.

      Si on veut que le script fonctionne aussi avec, par exemple, dash, sa commande echo ne prend pas en charge l’option -e, mais son printf ne prend pas en charge la séquence \e (échappement), contrairement à celui de bash ou celui de /bin (enfin on peut produire un échappement avec \033).

      Moralité : au pire printf fonctionne, contrairement à eche -e, mais sa prévisibilité est relative, surtout quand on veut produire des codes couleurs ANSI…

      « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

Suivre le flux des commentaires

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