IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes POSIX Discussion :

Récupérer les options et paramètres reçus pour les passer à une autre commande [KSH 93]


Sujet :

Shell et commandes POSIX

  1. #1
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut Récupérer les options et paramètres reçus pour les passer à une autre commande
    Bonjour,

    Je cherche à écrire une fonction générique qui extrait les options et leurs arguments d'une ligne de commande pour pouvoir les passer à une autre commande plus loin dans le programme .
    Je rencontre un problème lorsqu'un argument est vide ou contient une espace.
    Mon premier réflexe a été d'encadrer l'argument mais je n'obtiens pas le résultat attendu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #!/usr/bin/ksh93
     
    # La fonction qui affiche les options et paramètres reçus
    function ExtraitOpts {
      integer  Version=$1
      typeset  Options="$2"
      if (( $# > 2 ))
      then
        shift 2
        typeset  Opt Opts=""
        while getopts ":${Options}" Opt "$@"
        do
          if [[ ${Options} == *${Opt}:* ]]  # Opion avec argument
          then
            if (( Version == 1 )) || ( [[ -n ${OPTARG} ]] && ! [[ ${OPTARG} =~ [ ] ]] ) # Argument en plusieurs mots ou vide
            then
              Opts+="-${Opt} ${OPTARG} "
            else # Argument en plusieurs mots ou vide
              Opts+="-${Opt} '${OPTARG}' "
            fi
          else
            Opts+="-${Opt} "
          fi
        done
        shift $(( OPTIND - 1 ))
        if (( Version == 1 ))
        then
          print -eR ${Opts} "$@"
        else
          typeset Params=
          if [[ -n ${OPTARG} ]] && ! [[ ${OPTARG} =~ [ ] ]]
          then
            Params+="$1 "
          else # Paramètre en plusieurs mots ou vide
            Params+="'$1' "
          fi
          print -eR ${Opts} ${Params}
        fi
      fi
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # La fonction qui attend ces options et paramètres
    function Procedure {
      typeset Opt= ArgX= ArgY=
      integer Prm=1
      while getopts ':x:y:z' Opt "$@"
      do
        case  ${Opt}   in
          [xy]  ) echo "Opt : -${Opt} |${OPTARG}|"  ;;
          z     ) echo "Opt : -${Opt}"              ;;
        esac
      done
      shift $(( OPTIND - 1 ))
      while (( $# ))
      do
        echo "Prm$(( Prm++ )) = |$1|"
        shift
      done
      echo
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # Quelque lignes de commande pour tester
    Variable=$(ExtraitOpts 1 'x:y:z' -x abc -y def -z Version1)
    Procedure ${Variable}
     
    Variable=$(ExtraitOpts 1 'x:y:z' -x "Deux Mots" -y '' -z "Version 1" '')
    Procedure ${Variable}
     
    Variable=$(ExtraitOpts 1 'x:y:z' -y '' -x "Deux Mots" -z "Version 1" '')
    Procedure ${Variable}
     
    Variable=$(ExtraitOpts 2 'x:y:z' -x abc -y def -z Version2)
    Procedure ${Variable}
     
    Variable=$(ExtraitOpts 2 'x:y:z' -x "Deux Mots" -y '' -z "Version 2")
    Procedure ${Variable} 
     
    Variable=$(ExtraitOpts 2 'x:y:z' -y '' -x "Deux Mots" -z "Version 2" '')
    Procedure ${Variable}
    # Le résultat obtenu
    Opt : -x |abc|
    Opt : -y |def|
    Opt : -z
    Prm1 = |Version1|
    
    Opt : -x |Deux|
    Prm1 = |Mots|
    Prm2 = |-y|
    Prm3 = |-z|
    Prm4 = |Version|
    Prm5 = |1|
    
    Opt : -y |-x|
    Prm1 = |Deux|
    Prm2 = |Mots|
    Prm3 = |-z|
    Prm4 = |Version|
    Prm5 = |1|
    
    Opt : -x |abc|
    Opt : -y |def|
    Opt : -z
    Prm1 = |'Version2'|
    
    Opt : -x |'Deux|
    Prm1 = |Mots'|
    Prm2 = |-y|
    Prm3 = |''|
    Prm4 = |-z|
    Prm5 = |'Version|
    Prm6 = |2'|
    
    Opt : -y |''|
    Opt : -x |'Deux|
    Prm1 = |Mots'|
    Prm2 = |-z|
    Prm3 = |'Version|
    Prm4 = |2'|
    # Le résultat attendu sur la dernière commande
    Opt : -y ||
    Opt : -x |Deux Mots|
    Opt : -z
    Prm1 = |Version 2|
    La fonction originale est plus complexe et extrait seulement certaines options parmi la liste des options reçues.
    Il me reste la possibilité de traiter à chaque fois la ligne de commande en détail et enregistrer chaque argument dans une variable mais j'aurais aimé pouvoir me dispenser de recopier ce bloc de code en plusieurs exemplaires.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  2. #2
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Dans ce genre de démarche, il faut faire attention au nombre de fois que sont interprété les double quotes " ".

    Je ne connais pas ksh93, mais ne faut-il pas plutôt écrire un truc comme ceci, pour régler le problème ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Opts+="-${Opt} \"${OPTARG}\" "
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    J'avais déjà essayé (mais j'ai revérifié par acquit de conscience) mais celà ne change rien au comportement de la fonction : les apostrophes sont simplement remplacées par des guillemets et les arguments restent traités mot par mot.
    Opt : -y |""|
    Opt : -x |"Deux|
    Prm1 = |Mots"|
    Prm2 = |-z|
    Prm3 = |"Version|
    Prm4 = |2"|
    Merci quand même de t'être intéressé à mon problème.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Rajoute une couche.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Opts+="-${Opt} \\\"${OPTARG}\\\" "
    Ou plusieurs. Jusqu'à ce que ce satané double quote apparaisse. Puis -1.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    Le "satané" guillemet apparait bien. Mon problème c'est qu'il n'est pas interprété comme un caractère d'encadrement de chaine.

    A force de chercher, j'ai fini par trouver une solution en appelant ma procédure et sa variable contenant options et paramètres à travers la commande eval.

    Oui, je sais que eval is evil mais, pour le moment, c'est tout ce que j'ai trouvé.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 789
    Points
    30 789
    Par défaut
    J'ai trouvé !
    Je peux me dispenser d'eval en utilisant un tableau passé par référence à la fonction.

    Je donne la solution si cela peut aider quelqu'un d'autre

    La fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function ExtraitOpts2 {
      if (( $# > 2 ))
      then
        nameref Opts=$1
        typeset Options="$2"
        shift 2
        typeset Opt
        integer Idx=0
        while getopts ":${Options}" Opt "$@"
        do
          Opts[ $(( ++Idx )) ]="-${Opt}"
          if [[ ${Options} == *${Opt}:* ]]  # Option avec argument
          then
            Opts[ $(( ++Idx )) ]="${OPTARG}"
          fi
        done
        shift $(( OPTIND - 1 ))
        while (( $# ))
        do
          Opts[ $(( ++Idx )) ]="${1}"
          shift
        done
      fi
    }
    Son utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typeset -a Tableau
    ExtraitOpts2 Tableau 'w:x:y:z' -y '' -x "Deux Mots" -w '"' -z "Version 2" '' '"' "'"
    Procedure "${Tableau[@]}"
    Le résultat
    Opt : -y ||
    Opt : -x |Deux Mots|
    Opt : -w |"|
    Opt : -z
    Prm1 = |Version 2|
    Prm2 = ||
    Prm3 = |"|
    Prm4 = |'|
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 9
    Dernier message: 16/01/2020, 14h21
  2. Réponses: 1
    Dernier message: 08/02/2009, 15h43
  3. Réponses: 2
    Dernier message: 24/10/2007, 12h18
  4. Réponses: 2
    Dernier message: 29/08/2007, 19h43
  5. Réponses: 1
    Dernier message: 31/01/2007, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo