Forum Programmation.shell bash : construction d'une ligne de commande dont certains arguments contiennent des espaces

Posté par  (site web personnel) .
Étiquettes : aucune
0
12
oct.
2010

Bonjour,

Je me heurte à un problème que je peux contourner facilement, mais je voudrais savoir s'il existe une solution. Le problème vient de la manière de passer des arguments avec espaces à une commande appelée par un script bash. La difficulté vient dans la construction conditionnelle de la chaîne qui contient les arguments, et le fait de faire distinguer à bash l'espace et le séparateur d'arguments. L'extrait du programme :




#!/bin/bash
set -e

COWBUILDER_OPTS="--autocleanaptcache --debootstrap=cdebootstrap"
REQUESTED_DIST=lucid

case $REQUESTED_DIST in
# universe is required for ubuntu
hardy|jaunty|karmic|lucid|maverick)
COWBUILDER_OPTS+=" --components=\"main universe\""
;;
esac

for opt in $COWBUILDER_OPTS; do echo $opt; done


Le résultat :

$ ./script
--autocleanaptcache
--debootstrap=cdebootstrap
--components="main
universe"


Le résultat recherché :

$ ./script
--autocleanaptcache
--debootstrap=cdebootstrap
--components="main universe"


J'ai évidement essayé les divers échappement possibles, trouvé plusieurs bonnes descriptions du problème (comme [1]), mais aucune solution pour construire correctement ma ligne de commande selon certaines conditions comme l'exemple l'illustre.



[1] http://wiki.bash-hackers.org/syntax/quoting



Merci d'avance pour votre aide.

  • # en changeant de séparateur

    Posté par  . Évalué à 2.

    Je ne sais pas si ça répond à la question mais :
    
    #!/bin/bash
    set -e
    
    IFS=':'
    COWBUILDER_OPTS="--autocleanaptcache$IFS--debootstrap=cdebootstrap"
    REQUESTED_DIST=lucid
    
    case $REQUESTED_DIST in
        # universe is required for ubuntu
        hardy|jaunty|karmic|lucid|maverick)
            COWBUILDER_OPTS+="$IFS--components=\"main universe\""
            ;;
    esac
    
    for opt in $COWBUILDER_OPTS; do echo $opt; done
    unset IFS
    
    
    en ne restant qu'avec l'espace, je pense que ça va être compliqué quand même.
    • [^] # Re: en changeant de séparateur

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

      Merci, j'avais déjà lu des choses sur l'$IFS, mais par la suite ça me semble plus compliqué vu que je veux réutiliser cette variable pour construire une ligne de commande.
  • # array/liste

    Posté par  . Évalué à 4.

    cowbuilderOpts=( --autocleanaptcache --debootstrap=cdebootstrap )
    requestedDist=lucid

    case $requestedDist in
    # universe is required for ubuntu
    hardy|jaunty|karmic|lucid|maverick)
    cowbuilderOpts+=( --components="main universe" )
    ;;
    esac

    for opt in "${cowbuilderOpts[@]}"; do echo $opt; done
    Tu devrais prendre l'habitude de ne pas nommer tes variables tout en majuscules
    • [^] # case pour une seule condition ?

      Posté par  . Évalué à 2.

      Si tu n'as qu'un seul test sur requestedDist :
      [\[ $requestedDist =~ hardy|jaunty|karmic|lucid|maverick ]] && cowbuilderOpts+=( --components="main universe" )
      ira bien.

      PS: j'ai ajouté une \ entre les crochets pour les mettre en évidence, mais elle ne doit pas figurer dans le code !
    • [^] # Re: array/liste

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

      Impeccable, je savais qu'il y avait une solution! Merci. Ainsi, je peux invoquer ma commande directement de la façon suivante :
      # cowbuilder --create "${COWBUILDER_OPTS[@]}" --basepath=/path
      

Suivre le flux des commentaires

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