Forum Programmation.shell Substitution de commande et dialog

Posté par (page perso) .
Tags : aucun
1
19
nov.
2011

Bonjour,

je souhaite créer un menu dynamiquement via dialog dans un script sh.

Si dans mon script je met :

#!/bin/bash
dialog --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5 "openerp" "Installation d'OpenERP" off "lamp" "Installation du serveur web" off "security" "Installation de la partie securite" on


Le menu s'affiche correctement

Mais vu que le menu doit être dynamique, je construit ma commande dans une chaine que j'exécute avec la substitution de commande :

#!/bin/bash
plugin_options=$(list_plugins_for_menu "${plugins}")

dialog_command="dialog  --backtitle \"Choisissez les plugins à installer\" --title \"Plugins à installer\" --checklist \"Sélectionnez le ou les plugins à installer sur le serveur\" 20 61 5 ${plugin_options}"

echo ${dialog_command}
choices=$(${dialog_command})


Et dans ce cas, j'obtiens une erreur : "Error: Unknown option les. Use --help to list options."

Pour information :

  • ma fonction list_plugins_for_menu me retourne une chaine contenant les options de mon menu
  • ${plugins} est bien défini dans mon script
  • ${plugin_options} a pour valeur : "openerp" "Installation d'OpenERP" off "lamp" "Installation du serveur web" off "security" "Installation de la partie securite" on
  • la commande dialog que j'ai dans le script qui fonctionne est un copier-coller de celle qui est affiché avec le echo dans le script qui ne fonctionne pas.
  • de plus, que je passe par $() ou `` pour la substitution de commande, produit le même résultat.
  • enfin, même si je met sur une ligne juste ${dialog_command} sans $() ou `` le résultat produit est le même

Auriez-vous une idée ou au moins une direction vers laquelle je pourrais chercher afin de trouver d'où vient le soucis ?

  • # pourquoi ne pas faire simplement

    Posté par . Évalué à 4.

    #!/bin/bash
    plugin_options=$(list_plugins_for_menu "${plugins}")
    
    choices=$(dialog  --backtitle \"Choisissez les plugins à installer\" --title \"Plugins à installer\" --checklist \"Sélectionnez le ou les plugins à installer sur le serveur\" 20 61 5 ${plugin_options})
    
    

    sinon ton probleme vient peut-etre des " qui se trouve dans ${plugins_options} qui ne sont pas echappés dans ton dialog_command

    • [^] # Re: pourquoi ne pas faire simplement

      Posté par (page perso) . Évalué à 1.

      Ta solution fait avancé le problème, merci.

      Mais, le soucis vient maintenant de mon ${plugins_options} à mon avis car en faisant :

      #!/bin/bash
      plugin_options=$(list_plugins_for_menu "${plugins}")
      echo ${plugins_options}
      choices=$(dialog --stdout --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5 ${plugin_options})
      
      

      J'ai l'erreur :

      Error: Expected 3 arguments, found only 2.
      Use --help to list options.

      et ça m'affiche bien cela :

      "openerp" "Installation d'OpenERP" off "lamp" "Installation du serveur web" off "security" "Installation de la partie securite" on

      Donc, il me semble que les options sont bien échappées vu que le echo les affiche comme elles devraient l'être dans la commande, j'ai tort ?

      Pour résumer :

      • ceci fonctionne :

        #!/bash
        choices=$(dialog --stdout --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5 "openerp" "Installation d'OpenERP" off "lamp" "Installation du serveur web" off "security" "Installation de la partie securite" on)
        
      • ceci ne fonctionne pas :

        #!/bash
        plugin_options="\"openerp\" \"Installation d'OpenERP\" off \"lamp\" \"Installation du serveur web\" off \"security\" \"Installation de la partie securite\" on"
        
        choices=$(dialog --stdout --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5 ${plugin_options})
        

      Et je n'arrive pas à comprendre pourquoi...

  • # Les guillemets sont transmis

    Posté par (page perso) . Évalué à 3.

    Si je ne me trompe pas, les guillemets sont transmis tels quels, alors que tu t'attends à ce qu'ils soient supprimés par le shell.
    Exemple:

    $ commande="ls \".\""
    $ resultat=$($commande)
    ls: ".": Aucun fichier ou répertoire de ce type
    
    

    La barre oblique d'échappement ne fonctionne pas mieux.
    Il faut peut-être utiliser une astuce comme passer par xargs ou quelque chose du genre.

    • [^] # Re: Les guillemets sont transmis

      Posté par (page perso) . Évalué à 1.

      avec xargs, ça fonctionne parfaitement. Tu viens de sauver le reste de mes cheveux. Un immense merci !

      Le code qui fonctionne :

      #!/bin/bash
      plugin_options="\"openerp\" \"Installation d'OpenERP\" off \"lamp\" \"Installation du serveur web\" off \"security\" \"Installation de la partie securite\" on"
      
      echo ${plugin_options} | xargs dialog --args --stdout --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5
      
      
  • # une solution à base de printf

    Posté par . Évalué à 3.

    Ton problème est au lié fameux word splitting de bash ;)

    En tout cas, une solution avec ton code qui fonctionne :

    plugin_options="\"openerp\" \"Installation d'OpenERP\" off \"lamp\" \"Installation du serveur web\" off \"security\" \"Installation de la partie securite\" on"
    
    dialog --args --stdout --backtitle "Choisissez les plugins à installer" --title "Plugins à installer" --checklist "Sélectionnez le ou les plugins à installer sur le serveur" 20 61 5 $(printf -- '%s %s %s\n' $plugin_options)
    
    

    J'ai ajouté --args pour débuguer, CF -> dialog(1)

    Si besoin, tu peux quoter le printf, genre printf -- '"%s" "%s" "%s"\n'

    La façon dont tu code list_plugins_for_menu est important je pense.

    • [^] # Re: une solution à base de printf

      Posté par (page perso) . Évalué à 0.

      Tout d'abord, un grand merci pour ton lien vers le word splitting de bash, pendant mes recherches j'avais trouvé quelques références à ce concept mais le lien que tu me donnes est vraiment le mieux que j'ai pu lire.

      Ensuite, j'ai copier/coller ton code et cela me fait la même erreur qu'avant (en gros mes espaces dans mes libellés sont toujours considérés comme l'espacement entre 2 arguments)

      Enfin, j'ai compris le word splitting et vu qu'avec xargs (proposé au dessus) ça fonctionne, je pense que je vais arrêter de me prendre la tête à mettre mes arguments directement dans la commande

      merci beaucoup de ton aide.

  • # eval

    Posté par . Évalué à 0.

    J'arrive un peu après la bataille, mais au cas où.
    Il y aurait aussi une solution avec "eval".

    Exemple :

    height=20
    width=50
    title="--title 'Gestion des clés ssh'"
    eval "dialog $title --infobox '\n Montage du CDROM...' $height $width"
    
    

    Il faut donc remplacer toutes les guillemets doubles par des guillemets simples dans ta commande.
    Si ça peut aider...

Suivre le flux des commentaires

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