Journal Un meilleur shell

Posté par  (site web personnel) .
Étiquettes : aucune
0
8
nov.
2007
Bonjour,

Je vais vous parler d'un sujet qui m'intéresse, le shell. A mon avis le shell actuel qu'on a sur nos machines (souvent bash) a deux gros problèmes, et j'aimerais bien ouvrir une discussion là dessus à l'occasion d'un développement récent que j'ai fait.

1. L'expansion des variables

Tout d'abord, le premier problème du shell sh ou compatible est à mon avis, outre sa syntaxe parfois bizarre, le problème de l'expansion des variables. Pour justifier mes griefs sur la syntaxe, je dirais simplement que je ne vois pas pourquoi les routines sont délimitées par des { } et pas les constructions if/for/case, pourquoi le if se termine par fi, le case par esac et le for/while par done et non pas rof/elihw.

penchons-nous sur le problème de l'expansion des variables. Le problème c'est que le shell découpe les mots après l'expansion des variables, c'est à dire que :
var="mot1 mot2"
cmd a b${var}c d

est équivalent à :
cmd a bmot1 mot2c d
et non pas :
cmd a "bmot1 mot2c" d

Alors que dans le code source on ne voit que 3 arguments passés à la commande cmd (a, b${var}c, d), il y en a en fait réellement 4 (a, b$mot1, mot2c, d).

Ce comportement peut être désirable dans certains cas, mais parfois vraiment malvenu. Par exemple lorsqu'on manipule des noms de fichiers contenant des espaces. En gros cela impose lorsqu'on ne sait pas précisément ce qu'il y a dans la variable à toujours l'entourer de quotes, c'est à dire écrire "$var" au lieu de $var.

Non seulement les débutants qui commencent ne comprennent pas toujours cette subtilité et oublient les quotes, mais bien souvent aussi, des gens expérimentés les oublient en les pensant inutiles.

Un exemple concret. la distribution ArchLinux utilise des script bash pour compiler les logiciels et créer des paquets, on les appelle PKGBUILD (un peu similaires aux ebuilds de gentoo). L'exemple le plus courrant et qui sert de modèle à tous les PKGBUILD est¹:


build() {
cd $startdir/src/$pkgname-$pkgver
./configure --prefix=/usr
make || return 1
make prefix=$startdir/pkg/usr install
}


$startdir est le dossier dans lequel les sources se trouvent, et où les fichiers sont installés.

Ici on peut voir que $startdir n'est jamais entre quotes, c'est à dire qu'il est impossible de compiler un package si le chemin courrant contient des espaces !!! En effet, la première commande (cd) échoue déjà car au moins deux arguments lui sont passés en paramètres.

C'est ma première critique concernant la robustesse des script shell.

2. La lenteur

Bash, c'est lent. On le voit avec les script d'init, et je l'ai remarqué plus récamment en remplaçant mon script monolithique ~/.xsession par de nombreux scripts modulaires qui me permet à chaque démarrage de:
- me demander mon mot de passe ssh
- lancer quelques programmes comme xbindkeys, mpd
- demander quelle session lancer (E17, GNOME, KDE, Terminal ...)

Et je constate facilement que c'est lent.

Je sais bien que si on veut faire quelque chose de rapide, on utilise plus quelque chose comme python que bash, mais le shell a tout de même l'avantage de pouvoir facilement lancer des applications tierces facilement, éventuellement de manière asynchrone, en modifiant l'environnement, et en redirigeant les entrées/sorties. Si on veut faire la même chose avec un langage classique, je pense que c'est d'un coup moins facile (si on omet la fonction system() qui utilise d'ailleurs le shell).

Sans compter des projets complexe entèrement programmés en bash. Par exemple le gestionnaire de paquets de Nasgaïa est comme ça (ca a peut être changé depuis). Et ne serait-ce qu'afficher l'aide prend un temps fou.

je me demande alors dans quelle mesure (et je vous pose la question) il ne serait pas intéressant d'avoir un interpréteur shell (type sh ou autre) constamment chargé en mémoire qui pourrait rapidement exécuter n'importe quel script. Bien entandu une attention particulière doit être portée à la sécurité.

3. mon code

je vois ai dit que j'avais codé quelque chose, mais quoi ? J'ai commencé un shell basé sur le langage jam². Jam est un remplaçant à make(1) et possède un langage de script qui a les facultés suivantes :

- les variables ne contiennent pas une seule valeur, mais des listes de chaînes de caractères.
- lors de l'expansion des variables est le produit de tous les termes. Pour illustrer cela, je prend juste l'exemple donné dans la documentation³:

$(X) -> a b c
t$(X) -> ta tb tc
$(X).txt -> az bz cz
$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c


- la ponctuation n'est pas reconnue si elle n'est pas entourée d'espaces. Cela permet d'avoir de la ponctuation sans problèmes à l'intérieur des mots.

Ce que j'ai fait à partir de ça, c'est relativement simple. J'ai supprimé toute la partie qui s'occupait de la compilation, de la gestion des dépendances entre les cibles, pour ne garder que le langage Jam et faire en sourte que si une fonction n'est pas reconnue de manière interne par Jam, le programme correspondant dans le $PATH soit exécuté. Et cela n'a pris que quelques heures.

Mon code est disponnible sur launchpad⁴ et si cela vous intéresse, plus de détails dans mon e-mais sur la mailing list de jam⁵.

Des remarques ?

¹ http://wiki.archlinux.org/index.php/ABS_-_The_Arch_Build_Sys(...)
² http://freetype.sourceforge.net/jam/index.html
³ http://public.perforce.com/public/jam/src/Jam.html
https://code.launchpad.net/~mildred/+junk/jam-shell
http://maillist.perforce.com/pipermail/jamming/2007-November(...)
  • # iPython

    Posté par  . Évalué à 3.

    Je te conseille de regarder du côté d'iPython qui fournit un shell interactif un peu plus chiadé que celui d'origine. On peut l'utiliser en lieu et place de shell Unix traditionnel.
    http://ipython.scipy.org/moin/About

    Ce n'est qu'un retour aux origines, Python était destiné à servir de shell pour Amoeba.
  • # Y a pas que Bash dans la vie

    Posté par  . Évalué à 4.

    Y'a TCSH !
    • [^] # Re: Y a pas que Bash dans la vie

      Posté par  . Évalué à 10.

      Quitte à citer un shell Unix autre que Bash, autant citer zsh ;-)
      • [^] # Re: Y a pas que Bash dans la vie

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

        Je ne sais pas pour tcsh, mais je sais que zsh (que j'utilise) a les mêmes problèmes que bash.
        • [^] # Re: Y a pas que Bash dans la vie

          Posté par  . Évalué à 10.

          Dieu merci, tcsh ne souffre pas des mêmes problèmes que bash. A la place il souffre des mêmes problèmes que csh.
        • [^] # Re: Y a pas que Bash dans la vie

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

          Bah tu dois très certainement mal utiliser zsh ou l'utiliser à la bash.

          Car zsh permet autrement plus de choses que bash notamment en ce qui concerne la programmation. Une bonne lecture (longue) de http://zsh.dotsrc.org/Doc/ pourra te donner un bon apperçu.

          La lenteur du shell est relative, comme indiqué plus bas on passe souvent par des appels à des programmes externes (grep awk sed cat etc.) là où ce n'est absolument pas nécessaire en tout en zsh pour ce que je connais. Pour convertir souvent des script bash/ksh en zsh je peux te garantir que quand tu vires which/grep et consors tu as souvent un gain de performances important.

          d'ailleurs dans la foulée : dans la version de dev de zsh, un nouveau module est en train de faire son apparition : zcurses => exit dialog \0/.
          • [^] # Re: Y a pas que Bash dans la vie

            Posté par  . Évalué à 1.

            pourquoi utiliser dialog ?

            J'ai un collègue qui a fait de très belles choses en jouant avec les séquences terminfo...

            En plus c'est portable, ce qui n'est pas forcément le cas de dialog et encore moins du module nzcurses...
            • [^] # Re: Y a pas que Bash dans la vie

              Posté par  . Évalué à 2.

              c'est plus portable, mais c'est surtout plus bas-niveau, donc plus chiant à faire quoi que ce soit.
          • [^] # Re: Y a pas que Bash dans la vie

            Posté par  . Évalué à 4.

            Deja en (ba|k)sh, quand on commence à virer les "cat | grep" ou les series de "grep | grep | grep -v | cut | sed' par un bon vieux awk, on gagne en rapidité d'exécution.
            • [^] # Re: Y a pas que Bash dans la vie

              Posté par  . Évalué à 5.

              Je suis assez d'accord.

              Quand j'ai débuté la programmation shell j'enchainais beaucoup les |, et c'est vrai que les performances étaient pas au rendez-vous.

              Utiliser correctement le shell, c'est surtout limiter le nombre de process et utiliser toutes ls fonctionnalités offertes par ce dernier.

              Jusqu'au jour où finit par utiliser awk parce que le shell est trop pauvre, ensuite on découvre perl, et on fait des scripts perl standalone.

              Aujourd'hui quand je veux faire un truc un minimum compliqué, je ne pense même pas à le faire en shell, c'est trop inmaintenable, mais bon y en a qui aiment se faire chier alors bon...
              • [^] # Re: Y a pas que Bash dans la vie

                Posté par  . Évalué à 1.

                Si je suis bien le raisonnement, tu fais donc désormais des scripts en Perl pour que cela soit plus maintenable.

                C'est moi où il y a beaucoup d'ironie dans cette phrase ? :)
                • [^] # Re: Y a pas que Bash dans la vie

                  Posté par  . Évalué à 2.

                  Parce que pour toi un programme Perl est difficilement maintenable...?

                  J'ai ecris récemment un soft de 10 000 lignes environs de Perl, et c'est
                  tres maintenable et structuré.

                  Tout langage, mal ecris, donne du code difficilement maintenable...
                • [^] # Re: Y a pas que Bash dans la vie

                  Posté par  . Évalué à 2.

                  C'est toi.

                  Tu peux avoir l'opinion que tu veux dans la guéguerre (stupide) perl/python/ruby (ou une autre qui m'échappe), tu ne trouveras malgré tout pas grand monde pour prétendre qu'un gros projet bash est plus maintenable qu'un gros projet Perl.
                  • [^] # Re: Y a pas que Bash dans la vie

                    Posté par  . Évalué à 1.

                    Il n'a juste jamais prit le temps de lire le code source de FreeNX :) (c'est un gros script bash de je sais plus combien de ligne...)
              • [^] # Re: Y a pas que Bash dans la vie

                Posté par  . Évalué à 3.

                Aujourd'hui quand je veux faire un truc un minimum compliqué, je ne pense même pas à le faire en shell, c'est trop inmaintenable, mais bon y en a qui aiment se faire chier alors bon...

                Le shell, c'est bien lorsque tu te retrouve dans un environnement ou tu n'es pas sur d'avoir Perl à disposition partout (anciennes installations d'Unix proprios, NetBSD qui ne dispose pas de Perl dans une installation de base ou certaines boites qui interdisent l'utilisation de ce langage), ou quand tu développe des scripts de démarage par exemple.

                Puis il ya des cas ou il est plus simple de s'en sortir avec un awk bien senti qu'avec Perl (cela dit je suis un peu rouillé en Perl, faudrait que je m'y remette).
            • [^] # Re: Y a pas que Bash dans la vie

              Posté par  . Évalué à 0.

              Pour grep, il est souvent possible de s'en passer quand il sagit seulement
              de savoir si (une ligne, un mot, un process) est présent:


              a=`<fichier.txt`
              [ "${a//michu/}" != "${a}" ] && echo "MATCH" || echo "MATCH PAS"


              C'est nettement plus rapide que:

              cat fichier.txt | grep michu
              [ "$?" == "0" ] && echo "MATCH" || echo "MATCH PAS"



              Mais c'est dangereux si le fichier est gros.

              Pour traiter un fichier ligne par ligne:

              exec 3<fichier.txt
              while read -u 3 line ; do
              echo "${line}"
              # Traitement
              done
              exec 3>&-


              C'est plus rapide que:

              function processLines() {
              local line
              while read line ; do
              echo "${line}"
              done
              }
              cat fichier.txt | processLines



              Il y a pas mal de bidouilles pour gagner en perfs, par exemple avec
              les trucs décrits dans la section 'Parameter Expansion' on peut couvrir
              pas mal de cas en ce qui concerne le traitement de chaines de caractères.
              • [^] # Re: Y a pas que Bash dans la vie

                Posté par  . Évalué à 4.

                Le while read ligne est une abomination côté perfs.

                Imagine que dans ton traitement tu fais appel a des grep, cut ou sed, sur un fichier de plusieurs milliers de lignes c'est l'horreur.

                awk est un outil qui est justement fait pour traiter les fichiers ligne à ligne, c'est beaucoup plus efficace.
                • [^] # Re: Y a pas que Bash dans la vie

                  Posté par  . Évalué à 1.

                  Je ne cherchais pas à dire que c'est mieux que awk ou autre,
                  mais simplement de montrer que l'on peut se passer des pipes en bash et le gain en performances en est conséquent.
                  Sur de gros fichiers, il est évident que de faire des | grep , | awk ça rox.
                  Mais sur de petits fichiers et une machine lente, le pipe c'est lent (car fork si je ne me trompe pas).
                  Et si le processing fait appelle à d'autres outils du script bash pour inserer des trucs dynamiquement , définir des variables pour bash en fonction de certaines lignes, remplir un tableau (si si ça existe en bash) etc ..
                  Une pile de grep/awk n'est pas forcement plus efficace.

                  Et puis, le plus pénible avec ces tubes étant la difficulté à obtenir le code de retour de la première commande ce qui rend encors plus complexe la détection d'erreurs dans le script qui sont trop souvent négligées sous pretexte que ça n'arrive jamais.

                  >imagine que dans ton traitement tu fais appel a des grep, cut ou sed, sur un fichier de plusieurs milliers de lignes c'est l'horreur.

                  Si je montre comment éviter les grep, cut & autre, ce n'est pas pour en mettre dans le 'processing' de chaques lignes. Suis pas gros débile non plus, hein :-)
                  Utiliser un script shell pour traiter plusieurs milliers de lignes, c'est pas une super bonne idée non-plus.
  • # Re:

    Posté par  . Évalué à 4.

    > Des remarques ?

    Désolé, mais je n'ai pas tout compris.
    Le premier problème qui se pose, est de savoir quel est le domaine d'un shell. Que doit-il supporter ou non.
    Je ne pense pas que le shell doit tout faire et être un super language de programmation qui supporte tous les paradigmes.
    Comme l'a fait remarquer GeneralZod, il y a des alternatives à sh pour les cas pointus (python, perl, php, etc).

    Enfin, il y a le gros problème de la compatibilité si tu fais évoluer sh.

    > je me demande alors dans quelle mesure (et je vous pose la question) il ne serait pas intéressant d'avoir un interpréteur shell (type sh ou autre) constamment chargé en mémoire qui pourrait rapidement exécuter n'importe quel script.

    C'est un vrai/faux problème. Si Bash est utilisé, alors il est en cache. Son initialisation doit peut-être être optimisé.

    Pour les performances, c'est aussi un vrai/faux problème. bash n'est pas utilisé comme programme résident. Il exécute un script et basta. Lorsque mon système est booté, je n'ai plus de bash qui "traine" sauf si je lance xterm, etc...
    • [^] # Re: Re:

      Posté par  . Évalué à 5.

      D'autant plus que concernant les performances, il est possible d'avoir des choses assez rapide en évitant de lancer des process externes.

      Je pense que l'exemple de l'init est vraiment mal venu. D'abord chez moi, les scripts sont lancés en parallèle et le démarrage est très rapide, ensuite lors de l'init, ce sont les autres applications lancées qui prennent du temps. Le temps CPU consacré à l'interprétation doit être très faible.

      Par exemple :
      $ cat > toto1
      i=1 ; while [ $i -lt 1000 ] ; do FILE=toto/titi/tata ; echo ${FILE##*/} > /dev/null ; i=$(( $i + 1 )) ; done
      $ cat > toto2
      i=1 ; while [ $i -lt 1000 ] ; do basename toto/titi/tata > /dev/null ; i=$(( $i + 1 )) ; done

      $ time ./toto1
      ... 0:00.09elapsed ...
      $ time ./toto2
      ... 0:01.36elapsed ...

      "basename" est une commande, on voit que la version 100% bash est beaucoup plus rapide. Suffisamment rapide pour ce qu'il est censé faire.
      • [^] # Re: Re:

        Posté par  . Évalué à 5.

        Lors de l'init, ce sont les autres applications lancées qui prennent du temps. Le temps CPU consacré à l'interprétation doit être très faible.


        Je pense aussi. Concrètement, pendant le démarrage, plusieurs milliers de processus sont lancés! Et si lancer un processus ça coûte relativement peu, en lancer plusieurs milliers, c'est très coûteux, surtout lorsque le processus s'arrête quasi aussitôt! Il a fallu aller le chercher sur disque (ça, c'est très coûteux en temps), le charger en mémoire, faire l'édition de lien dynamique et donc aller chercher sur disque les librairies,... Lors du démarrage, certains processus mettent peut-être plus de temps à se lancer qu'à faire leur travail!!

        On voit d'ailleurs la différence entre un premier lancement et les suivants:
        mfertre@paraphrase:~$ time /bin/echo toto
        toto

        real 0m0.060s
        user 0m0.000s
        sys 0m0.004s
        mfertre@paraphrase:~$ time /bin/echo toto
        toto

        real 0m0.002s
        user 0m0.000s
        sys 0m0.000s

        Sur un processus qui demande 2 milli-secondes de travail, il en a fallu 64 lors d'un premier appel!

        En faisant un calcul tout à fait à la louche, en admettant que 1000 processus correspondant à des exécutables différents soient lancés lors du démarrage (bon, je pense pas quand même, il doit y avoir beaucoup de bash, grep, sed, awk, sort, cut, touch, etc.), ça prendrait environ (64-2ms * 1000) soit environ 1 min (ne soyons plus à une approximation près) ! Sans compter le temps de traitement!
    • [^] # Re: Re:

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


      Le premier problème qui se pose, est de savoir quel est le domaine d'un shell. Que doit-il supporter ou non.
      Je ne pense pas que le shell doit tout faire et être un super language de programmation qui supporte tous les paradigmes.
      Comme l'a fait remarquer GeneralZod, il y a des alternatives à sh pour les cas pointus (python, perl, php, etc).


      Pas du tout, je ne veux pas faire un shell avec les fonctionnalités d'un langage de programmation complet. je parle juste de la manière dont sont évaluées les variables, c'est tout.

      D'ailleurs quand on regarde le langage Jam, il est loin d'être évolué. Cela ne l'empêche pas d'être compatible avec les espaces.

      Je pense que le langage de shell doit être simple, et ne pas permettre de faire des erreurs comme le permet sh. Et comme j'aimais bien Jam, je me suis ammusée a faire un shell avec le langage Jam.
      Et en passant, mon but ce n'est pas de faire un shell intéractif, mais plutôt de scripts.

      Sinon, je viens de penser qu'il me manque les pipes ... Je savais bien que programmer à 3h du matin me ferait oublier quelque chose :) Il faudra voir comment intégrer cela au langage ...
      • [^] # Re: Re:

        Posté par  . Évalué à 0.

        > Pas du tout, je ne veux pas faire un shell avec les fonctionnalités d'un langage de programmation complet. je parle juste de la manière dont sont évaluées les variables, c'est tout.

        Pas de problème.
      • [^] # Re: Re:

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

        >Cela ne l'empêche pas d'être compatible avec les espaces

        Bash est compatible avec les espaces.

        gnumdk@sarge:~$ for i in a "b${var}c" d; do echo $i; done
        a
        bmot1 mot2c
        d
        gnumdk@sarge:~$ IFS=
        gnumdk@sarge:~$ for i in a b${var}c d; do echo $i; done
        a
        bmot1 mot2c
        d

        Ce qui te fait chier c'est la valeur de IFS.

        Mais la bonne méthode quand on code un script est de toujours mettre "" autour d'une variable, meme si on est sur qu'il y'aura pas d'espace, au cas ou pour l'avenir...
  • # Fonctionnalitées

    Posté par  . Évalué à 3.

    Il faut voir qu'un shell, n'est pas un simple lanceur de commande, il y a un gros travail de fait sur la completion, sur la gestion des jobs, sur les pipes, les redirections. Est-ce que tu implementes la gestions les jobs?

    Ensuite, on l'utilise pour des raisons historiques, bash est présent sur tous les systèmes, du moins on trouve forcement un interpreteur sh.
    Ce qui facilite la vie des admins, c'est en partie pour ca que les autotools n'utilisent que des outils unix standard: la portabilité au détriment de la vitesse.

    De plus il existe différent shell plus ou moins rapide avec des syntaxes plus ou moins différentes. De ce que tu decris tu as envi d'un équivalent du language c, utilise alors tcsh, csh, ou (celui que je prefere parmis tous) zsh.
    au niveau des syntaxes:
    sh: sh, bash, zsh
    c: zsh, tcsh, csh
    k (mélange de csh/sh): ksh

    Le shell n'est pas un language pour programmer à mon avis, mais plutot pour bidouiller le système, il est assez difficile de faire des programmes serieux en shell qui soit portable. En loccurence je développe une conf pour bash/ksh/tcsh/zsh qui utilise exactement les mêmes fichiers pour chaques shell, et chaque shell voir version de shell a ses spécificités, j'ai donc une library de fonction portable entre tous les shells.
    Et toujours pour en revenir au problèmes principales pour les shells à mon avis, c'est la portabilité, et la donc la disponibilité par default d'un interpreteur sh sur tous les systemes. Sinon pour ce meme projet(il n'y as pas que la configuration des shells) j'aurai utilisé un autre language, et pas question non plus de distribuer des sources a compiler, car par exemple sous cygwin il n'y a pas forcement le compilo d'installé.

    PS: le proj en question est www.sf.net/projects/grk
    • [^] # Re: Fonctionnalitées

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


      Il faut voir qu'un shell, n'est pas un simple lanceur de commande, il y a un gros travail de fait sur la completion, sur la gestion des jobs, sur les pipes, les redirections. Est-ce que tu implementes la gestions les jobs?


      Pour le moment, ce que j'ai fait c'est juste un travail de 5/8 heures, donc il n'y a pas tout. Comme je ne prévoit pas de faire un shell intéractif (le langage jam ne s'y prete pas bien je pense, trop d'espaces), je vais passer sur la completion.

      Pour les jobs, on peut déjà lancer un rogramme en arrière plan, il reste a améliorer l'implémentation (si le parent meurt avant ses enfants, wait, disown). Et à part ça, je crois que c'est tout.

      Pour les pipes, soit j'utilise la syntaxe '|' (et il faut que je modifie la syntaxe Jam, demande un peu de travail), soit je fais autrement. Ce que je pensait c'est implémenter ça d'une autre manière. Pour les redirections, c'est prévu et pas implémenté.

      Je trouve que les pipes sont un peu trop linéaires. En gros une commande ne peut donner son résultat qu'a une seule autre commande, et pas à plusieurs. Je pense que ça pourrait être intéressant de permettre d'avoir plusieurs consommateurs pour un seul producteur.
      Pour l'inverse (plusieurs producteurs pour un seul consommateur) ça me paraît plus difficile...


      Mais ce qui m'intéresse vraiment, c'est pas forcément de produire quelque chose de viable (je ne pense pas que j'auais le temps de finir mon jam-shell) mais pluutôt de voir ce qui est possible et de rêver un peu. Je trouve l'expansion des variables à la Jam tellement mieux que celle de sh ...
      • [^] # Re: Fonctionnalitées

        Posté par  . Évalué à 4.

        Comme je ne prévoit pas de faire un shell intéractif (le langage jam ne s'y prete pas bien je pense, trop d'espaces), je vais passer sur la completion.

        Si ton truc n'est pas interractif alors ce n'est pas un shell, c'est juste un language de script de plus.
  • # Fish

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

    A l'époque j'avais fait un journal sur le shell innovant Fish : http://linuxfr.org/~patrick_g/18270.html

    L'article Wikipedia sur Fish : http://en.wikipedia.org/wiki/Friendly_interactive_shell

    Je sais pas ou ça en est mais je trouve déjà que l'amélioration de la syntaxe est massive par rapport à Bash.
    • [^] # Re: Fish

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

      Sauf que fish (comme son nom l'indique) se focalise plus sur l'intéractivité que sur les scripts. Et je ne me rappelle pas qu'il y ait tant d'améliorations (si ce n'est une cohéence à toutes les structures de programmation)
  • # heu ...

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

    C'est pas pour etre mechant, mais tout les shell ne se comportent pas comme bash.

    exemple :

    voila un ptit code code python :


    #!/usr/bin/python
    import sys

    if len(sys.argv) != 4 :
    print "pas 3 arguments : %d argument"%(len(sys.argv) - 1)
    else :
    print "3 arguments"

    print str(sys.argv[1:])


    en bash comme prevu :

    $ var="mot1 mot2"
    $ python test.py a b${var}c d
    pas 3 arguments : 4 argument
    ['a', 'bmot1', 'mot2c', 'd']


    mais en zsh (le seul le grand l'unique)

    tmp/jeu %var="mot1 mot2"
    /tmp/jeu % ./test.py a b${var}c d
    3 arguments
    ['a', 'bmot1 mot2c', 'd']


    Donc en zsh .. ben ca marche
    • [^] # Re: heu ...

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

      C'est pas pour etre mechant, mais tout les shell ne se comportent pas comme bash.


      C'est pour ça que je précise bien sh ou bash, car effectivement, il existe plein de shell différents.

      par contre pour le coup du zsh tu me surprend, mais effectivement tu as raison. Et moi qui pensait que bash était compatible sh ...
      mais, j'hésite à utiliser zsh comme langage de script, car j'ai l'impression que c'est plus un shell intéractif. Et que son comportement peut être différent selon la configuration.

      Alors j'hésite a faire quelque chose en zsh qui marchera chez moi (car j'ai certaines option activées ou non) mais qui ne marche pas ailleurs (car d'autres options sont activées). Ceci dit, je n'ai jamais testé et il y a peut être un moyen simple de résoudre ce problème.
  • # dash

    Posté par  . Évalué à 2.

    Si bash c'est lent, tu peux essayer dash.
    Dash est un shell comptible POSIX, il est beaucoup plus petit que bash, et il execute les script plus rapidement que bash.
    C'est le shell utilisé par défaut pour /bin/sh dans Ubuntu.
    http://en.wikipedia.org/wiki/Debian_Almquist_shell
    • [^] # Re: Dash vs Linux

      Posté par  . Évalué à 3.

      second degré :
      « Madame Chombier, contre votre baril de Linux je vous offre deux barils de Dash !
      - Ah ben nan alors ! Je préfère garder mon baril de Linux. »
  • # Nul !

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

    Le caractère intuitif doit fortement dépendre des gens alors parce que ça :

    $(X).txt -> az bz cz

    je ne trouve pas ça très logique !
    • [^] # Re: Nul !

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

      En fait j'avais commencé par modifier l'exemple pour montrer qu'on pouvait facilement rajouter une extension à plusieurs basenames, mais j'ai changé d'avis en cours de route. la bonne réponse est :

      $(X).txt -> a.txt b.txt c.txt
      $(X)z -> az bz cz


      Merci de me pointer cette grossière erreur
      • [^] # Re: Nul !

        Posté par  . Évalué à 7.

        Et quand on veut juste faire une concaténation de $X et de "z", on fait comment ?

        Je ne sais pour les autres, mais la concaténation me semble quand même beaucoup plus fréquente que la distribution.

Suivre le flux des commentaires

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