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 GNU Discussion :

Renvoyer un tableau depuis une commande


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut Renvoyer un tableau depuis une commande
    Bonjour,

    j'utilise une fonction qui me renvoie une liste via la création d'une variable que je peux réutiliser après.

    Je souhaiterai convertir cette fonction en une "vraie" commande.

    Mon soucis est de renvoyer une liste lorsque j'appelle la commande.

    Afin que je comprenne bien, simplifions la commande (qui n'a que peu d’intérêt mais bon :p ), on lui entre des valeurs, elle crée une liste avec et ne la renvoie que partiellement (genre les clés 1 et 3) :
    Il faudrait donc que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    variable=($(ma_super_commande oui non ouioui nononon)) 
     
    # Crée une liste mais ne doit me renvoyer que :
    # liste[1] qui vaut non
    # liste[3] qui vaut nonnon
     
    # Ainsi je devrais obtenir :
    echo "${variable[@]}"
    non nononon
     
    echo "${!variable[@]}"
    1 3
    j'arrive à renvoyer les textes via des echo mais comment faire pour qu'au final j'ai une liste avec conservation des clés ?

    Le but est bien évidemment qu'il n'y ait rien à faire pour l'utilisateur hormis appeler la fonction... (car oui on pourrait facilement boucler après coup dessus pour créer la liste).

    Merci à vous
    Sous Kubuntu 20.04

  2. #2
    Expert éminent sénior Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Points : 12 264
    Points
    12 264
    Par défaut
    J'ai rien compris

    que veux tu faire véritablement ?
    qu'est ce que "vraie commande" signifie ?
    exemple d'entrée et exemple de résultat attendu ?

    Merci

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    le terme "vraie" commande n'est pas en effet pas bon, c'est juste appeler un script au final mais dont je veux récupérer des informations.


    que veux tu faire ?
    exemple d'entrée et exemple de résultat attendu ?
    C'est ce que je pensais avoir fait...


    Comment récupérer un tableau en conservant ses clés et de ses valeurs depuis l'appel d'un autre fichier ?

    j'appelle ma super commande qui doit me renvoyer un tableau dans une variable donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x=($(ma_super_commande))
     
    echo ${x[@]}
    valeur1 valeur3
     
    echo ${!x[@]}
    1 3
    Encore une fois, on se fiche de ce que fait la super commande car au final, je cherche à comprendre comment (et si c'est possible) récupérer un tableau et ce sans avoir rien à faire de particulier pour l'utilisateur.

    Mon but est d'eviter que l'utilisateur ait besoin de faire genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    x=($(ma_super_commande))
     
    echo ${x[@]}
    1:valeur1 3:valeur3
     
    y=()
    for elem in "${x[@]}"
    do
      y[${elem%%:*}]="${elem#*:}"
    done
    ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    x=()
    while IFS+=":" read num elem
    do
      # La commande me renvoie des lignes de type : Numero:Valeur
      x[${num}]="${elem}"
    done < <(ma_super_commande)
    Cela fonctionne mais demande du traitement post commande, ce que je voudrais vraiment éviter.

    En espérant avoir été plus clair... ( et que ce soit possible)
    Sous Kubuntu 20.04

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 377
    Points
    19 377
    Par défaut
    Bonjour,

    un script accepte des paramètres "individuels", pas des tableaux.

    le seul "tableau" accessible par défaut dans un script est $@, qui contient la liste des tous les arguments du script.

    aqjs, il faudra parser la sortie de ta super commande pour y récupérer les informations.

    pour info, x=($(ma_super_commande)) est une mauvaise façon de faire, car le découpage de la sortie de la commande en éléments du tableau est fonction de l'IFS.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ maFonc() { echo "bla bla 'tra la la' \"la lère\"";}
    $ monTableau=( $(maFonc) )
    $ printf '%s\n' "${monTableau[@]}" 
    bla
    bla
    'tra
    la
    la'
    "la
    lère"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ maFonc() { echo "bla bla:tra la la:la lère";}
    $ IFS=':' monTableau=( $(maFonc) )
    $ printf '%s\n' "${monTableau[@]}" 
    bla bla
    tra la la
    la lère
    mais ça ne répond pas à ton interrogation.
    et pour pouvoir faire un while read line efficace, il faudrait que ta super commande affiche les informations ligne par ligne.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Ca doit être un super bordel dans ma tête XD
    du coup mes explications s'en ressentent.

    mon but n'est pas d'utiliser un while read ou quoi que ce soi derriere.

    Essayons autrement... mmmhhh :

    imaginons qu'un script fait tout un travail et doit me renvoyer un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    # Il contient 2 valeurs
    echo ${Tableau[@]}
    oui non
     
    # il contient 2 clés mais pas 0 et 1 forcement...
    echo ${!Tableau[@]}
    0 5
    Je souhaiterait lorsque je fais appel à ce script via une commande type :
    obtenir le même résultat que ci dessus, c'est à dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    echo ${x[@]}
    oui non
     
    echo ${!x[@]}
    0 5
    Actuellement j'en suis à :
    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
    variable=()
    while read line
    do
      # Me renvoie les lignes :
      # 0:oui 
      # 5:non
      # Je traite les lignes afin de séparer la clé et la valeur
      variable[${line%%:*}]="${line#*:}"
    done < <(ma_commande)
     
    echo ${variable[@]}
    oui non
     
    echo ${!variable[@]}
    0 5
    J'ai donc bien le résultat escompté.

    Mais mon but est de supprimer tout le traitement présent ici et de le délocaliser dans ma fameuse commande afin qu'un appel à ma commande suffise à me renvoyer le résultat.

    Mais cela ne me semble pas possible...
    Sous Kubuntu 20.04

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 377
    Points
    19 377
    Par défaut
    il me semble avoir bien compris.

    en deux mots : pas possible.

    un script ne renvoie pas un tableau, il affiche des données "brutes".
    et l'insertion dans un tableau de la sortie d'une commande n'en préserve pas l'apparent format tabulaire, puisqu'un script ne sort pas un tableau...
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    OK merci beaucoup à vous d'avoir pris le temps d'essayer de me comprendre !

    Dommage que ce soit pas possible
    Sous Kubuntu 20.04

  8. #8
    Expert éminent sénior Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Points : 12 264
    Points
    12 264
    Par défaut
    je confirme maintenant que je vois le besoin.
    C'est juste impossible.

    il faut penser ça autrement, par exemple passer via un fichier de sortie crée par un script (à toi de choisir le format, cvs, xml, yml,html,etc...) peut importe de là un autre script, utilisateur, etc... peut aller chercher ces informations et travailler dessus.

    mais ce n'est pas

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Merci,
    ce qui me rassure c'est que j'étais bien partie comme il le fallait
    Sous Kubuntu 20.04

  10. #10
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    c'est ça que tu cherches ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ x=(["0"]="oui" ["5"]="non")
    $ echo ${x[@]}
    oui non
    $ echo ${!x[@]}
    0 5

  11. #11
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    En fait c'était ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function test { echo "[0]='oui' [5]='non'" }
     
    x=( $(test) )
     
    $ echo ${x[@]}
    oui non
     
    $ echo ${!x[@]}
    0 5
    Mais ce n'est pas possible.
    Sous Kubuntu 20.04

  12. #12
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    et test (mauvais choix de nom) doit obligatoirement être une fonction, ça n'est pas envisageable de sourcer un fichier pour récupérer le tableau, quitte à le recopier ensuite par exemple ?
    Code script1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    source script2
    x=(${tab[@]})
    echo ${x[@]}
    echo ${!x[@]}
    Code script2 : Sélectionner tout - Visualiser dans une fenêtre à part
    tab=(["0"]="oui" ["5"]="non")

  13. #13
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    en réalité ce n'est pas une fonction mais un script (un autre fichier) qui est lancé et non une fonction (ça permet d'utiliser getops entre autre).
    Du coup le source ne fait pas exactement pareil...
    Sous Kubuntu 20.04

  14. #14
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 276
    Points : 12 717
    Points
    12 717
    Par défaut
    Bonjour,
    Peut-être une piste (mais dangereux) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ unset x
    $ titi() { echo "[0]='oui' [5]='non'" ;}
    $ eval x=($(titi))
    $ echo ${x[@]}
    oui non
    $ echo ${!x[@]}
    0 5
    Cordialement.

  15. #15
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Je connais quelqu'un qui dit toujours : "eval c'est mal" :p
    Sous Kubuntu 20.04

  16. #16
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 377
    Points
    19 377
    Par défaut
    « une piste (mais dangereux) »
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 276
    Points : 12 717
    Points
    12 717
    Par défaut
    C'est vrai, mais on peut quand on maîtrise l'évaluation et que l'on ne peut pas faire autrement.
    Le problème de eval, c'est que l'on peut détourner ce qu'il doit évaluer pour y introduire un peu n'importe quelle commande à des fins de corrompre le système.
    Pour faire simple, il peut introduire de gros problème de sécurité, sauf si ce qu'il doit évalué est bien circonscrit et donc ici, tu dois te poser la question si l'utilisateur pourra lui faire évaluer des commandes ou si le script qui fournit le résultat qui passe dans l'évaluation ne permettra jamais d'évaluer des commandes...
    Cordialement.

  18. #18
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Oui oui j'ai bien lu ce qui était écrit

    Je connais un peu eval, je sais qu'il est très puissant mais relativement dangereux aussi comme tu le précise dans tes explications.

    Je pense rester dans mon système actuel, un peu moins pratique mais sans risque.

    encore merci pour vos propositions.
    Sous Kubuntu 20.04

  19. #19
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    C'est amusant parce que, pour un besoin personnel, ça fait 2 jours que je suis sur cette même question: comment une fonction shell pourrait "retourner" à son appelant un tableau... (j'utilise "retourner" au sens habituel des fonctions du lambda-calcul)

    C'est quelque chose qui est tellement courant dans la plupart des langages de programmation qu'on aimerait bien avoir quelque chose d'identique en shell...
    mais, apparemment, c'est pas simple, voire impossible...

    Pour le fun, j'ai trouvé ceci (mais attention: eval is evil...):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    maFonc() {
      local result
      declare -a result=([1]=hello [3]=world [5]='and "goodbye"!')
      declare -p result
    }
    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
    $ temp=$(maFonc) # Je récupère la valeur "retournée" par la fonction dans une variable temporaire
     
    $ echo "temp: '$temp'"
    Temp: 'declare -a result='([1]="hello" [3]="world" [5]="and \"goodbye\"!")''
     
    $ eval "${temp/result=/x=}" # D'un coup de baguette magique, je transfère le résultat dans une variable "x"...
     
    $ echo "Valeurs: ${x[@]}"
    Valeurs: hello world and "goodbye"!
     
    $ echo "Indices: ${!x[@]}"
    Indices: 1 3 5
     
    $ declare -p x # Pour vérifier l'ensemble des valeurs
    declare -a x='([1]="hello" [3]="world" [5]="and \"goodbye\"!")'

  20. #20
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    Au final je vais le passer en résolu mais je vais éviter de l'utiliser eval (le mal est toujours tentant :p )
    Sous Kubuntu 20.04

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 5
    Dernier message: 15/04/2005, 14h22

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