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 :

Appel de commande dans une variable


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Points : 16
    Points
    16
    Par défaut Appel de commande dans une variable
    Bonjour,

    je dois modifier un script shell et je suis complètement novice dans le domaine.

    Je m'arrache les cheveux sur quelque chose qui me semblait pourtant être d'une facilité déconcertante... cela montre mon niveau...

    Je veux simplement exécuter dans mon script shell une commande qui est positionnée dans une variable. Je précise que la commande est une commande "complexe" (enchainement de commandes avec pipe).

    Pour simplifier, prenons l'exemple suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TOTO="ls | cat"
    $TOTO
    Je pensais que la ligne "$TOTO" allait permettre d'exécuter ma commande "ls | cat" mais apparament non.
    Cela fonctionne pour des commandes non enchainées (sans pipe) mais pas pour des commandes enchainées.

    J'ai également essayé avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TOTO="ls | cat"
    `$TOTO`
    mais cela ne fonctionne pas non plus.

    Est-ce ce quelqu'un est en mesure de m'expliquer pourquoi cela ne fonctionne pas, et surtout, comment faire pour y parvenir...

    J'avais prévenu que ça n'était pas d'un haut niveau

    Merci par avance

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

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


    c'est, ainsi que le montre la sortie de , comme si tu tapais :; or, les apostrophes protègent la commande pipe (|) d'être interpétée.

    le conseil commun, pour les commandes complexes, est d'utiliser une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mesCmd() { cmd1 | cmd2 ;}

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    merci beaucoup pour ta réponse

    Effectivement, cela fonctionne comme cela...

    En revanche, cela va compliquer mon code. En gros, je gérais des appels à find avec des commandes complexes différentes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    case $TOTO in
    	1) MON_FIND="find ... | ..."
            2) MON_FIND="find ... | ..."
            ...
    $MON_FIND > toto
    Cela veut dire que je dois créer autant de fonctions que de cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    case $TOTO in
    	1) ma_fonction_1 > toto
            2) ma_fonction_2 > toto
            ...
    Confirmes-tu que c'est comme cela que je dois m'y prendre ? Cela me semble faire beaucoup de fonctions à créer pour un code si simple

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2007
    Messages : 467
    Points : 647
    Points
    647
    Par défaut
    Salut,

    Tu peux aussi faire d'une autre manière comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MesDossiers=`ls`
    echo $ls
    Ou encore une autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MesDossiers="ls"
    eval $MesDossiers

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    Je ne vois pas ce que ça change :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case $TOTO in
    	1) monFind() { find ... | ...;}
            2) monFind() { find ... | ...;}
            ...
    monFind > toto
    si éventuellement tu ne te ressers pas de la fonction plus tard dans ton script, et que ton case n'affiche rien d'autre sur la sortie standard :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case $TOTO in
    	1) find ... | ...
            2) find ... | ... 
            *) echo "erreur" >&2
    esac > toto

  6. #6
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Salut,

    Citation Envoyé par Fanny28 Voir le message
    Cela me semble faire beaucoup de fonctions à créer pour un code si simple
    Sans voir ton code dans sa totalité et sans en connaitre la finalité, difficile de dire si c'est trop lourd et de t'aider à optimiser le tout

  7. #7
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Autre solution si tes commandes sont similaires, alimenter une ou plusieurs variables dans le case qui sera(ont) utilisée(s) après coup pour comme argument de tes commandes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case $TOTO in
    	1) MON_FIND="..."
            2) MON_FIND="..."
            ...
    find ... $MON_FIND ... | ... > toto
    Attention, car selon les options, tu pourrais avoir à utiliser xargs pour construire les arguments de find :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case $TOTO in
    	1) MON_FIND="..."
            2) MON_FIND="..."
            ...
    echo $MON_FIND | xargs find | ... > toto
    Mais bon, avec un exemple complet, on pourrait te donner une vraie bonne méthode, car cela dépend beaucoup de ce que tu cherches à faire exactement

    Si cela se trouve, tu n'as peut-être même pas besoin d'un pipe ?!

  8. #8
    Membre averti Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Points : 337
    Points
    337
    Par défaut
    Veuillez pardonner mon ignorance, mais :

    Citation Envoyé par Fanny28 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TOTO="ls | cat"
    $TOTO
    Pourquoi ne pas se contenter d'un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    TOTO="ls | cat"
    eval "$TOTO"
    Ce qui semble très bien marcher chez moi ?

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Points : 16
    Points
    16
    Par défaut
    Ouah, je ne pensais pas avoir autant de réponses, merci à tous .

    Je n'ai pas donné trop de détails car je ne souhaitais pas que des gens perdent trop de temps à effectuer mon travail
    Je voulais donc une petite aide sur quelque chose qui me semblait basique, ce que j'ai largement obtenu, et après, c'est à moi de m'y coller quand même.

    La solution proposée par FRUiT semble fonctionner (je ne l'ai pas encore testée dans mon script mais sur des petits tests à côté).
    Y-a-t-il une raison pour que les autres membres n'aient pas proposé cette solution ?
    Est-ce que vous n'y aviez pas pensé ou est-ce volontaire parce qu'il faut éviter d'utiliser eval (je ne sais pour quelle raison).

    Du coup, je passe le problème à résolu même si FRUiT et moi attendons de savoir si l'utilisation de eval est correcte. J'espère que c'est la bonne procédure.

    En tout cas, encore un grand merci à tous !

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    en l'occurrence, je ne l'ai pas proposé, parce que je ne vois pas de bonne raison de activer un comportement qui a été inhibé.

    l'utilisation d'une fonction est beaucoup plus simple

  11. #11
    Membre averti Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Points : 337
    Points
    337
    Par défaut
    Citation Envoyé par Fanny28 Voir le message
    La solution proposée par FRUiT semble [...]
    Rendons à César etc... En fait ce serait plutôt la solution qu'a proposé Luc1an0. Comme je l'utilise aussi dans un de mes scripts qui extrait des commandes dans des fichiers (et donx, comportant éventuellement des pipes), je me demandais ce qu'elle avait de non orthodoxe.

    Après pour la question de réactiver un comportement inhibé, c'est pas faux encore que, je ne sais pas quelles raisons poussent le shell à inhiber le comportement du pipe... On peut aussi se demander en quoi c'est dangereux ou mal en dehors du fait que c'est algorithmiquement amoral/paradoxal.

    En tout cas merci N_BaH pour l'explication.

  12. #12
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Citation Envoyé par Fanny28 Voir le message
    Je n'ai pas donné trop de détails car je ne souhaitais pas que des gens perdent trop de temps à effectuer mon travail
    C'est tout à ton honneur Tu peux toujours poster ta solution une fois prête si tu veux que l'on te propose quelque chose d'éventuellement plus adapté :p

    Sinon, outre l'explication de N_BaH, l'utilisation d'eval est parfois déconseillée à cause des problèmes potentiels de sécurité que cela peut potentiellement poser.

    Enfin, il y a également la possibilité d'utiliser 2 variables distinctes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ MON_LS="ls -l"
    $ MON_CAT="tail -3"
    $ $MON_LS | $MON_CAT
    -rw-r--r--  1 user users       538 Mar  9 16:11 test_sort.xml
    drwxr-xr-x  4 user users      4096 May  6 09:56 tmp
    drwxr-xr-x  2 user users      4096 Feb 18 09:46 vpn
    Avec toujours le risque d'avoir à utiliser xargs

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

Discussions similaires

  1. Récupérer la dernière commande dans une variable
    Par ssc37 dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 09/10/2009, 12h39
  2. Réponses: 5
    Dernier message: 26/09/2009, 02h11
  3. Mettre le résultat d'une commande dans une variable
    Par daviddu54 dans le forum Scripts/Batch
    Réponses: 12
    Dernier message: 18/09/2008, 23h58
  4. Le résultat d'une commande dans une variable ?
    Par kilkikou dans le forum Linux
    Réponses: 5
    Dernier message: 19/10/2007, 23h23
  5. [Mail] comment inclure une commande dans une variable
    Par pierrot10 dans le forum Langage
    Réponses: 8
    Dernier message: 27/04/2006, 20h17

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