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 :

[Bash] Fournir un pipe en paramètre à une fonction


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mars 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2010
    Messages : 74
    Par défaut [Bash] Fournir un pipe en paramètre à une fonction
    Salut !

    J'essaie de créer une fonction toute bête qui à un moment exécute ce qu'on lui envoie :

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function f() { $*; echo coucou; }
    Mais je n'arrive pas à fournir à cette fonction le paramètre pipe : |

    Voici mes tests :

    wc est executé après f ls -l, comme un pipe normal quoi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    f ls -l \| wc -l
    f "ls -l | wc -l"
    f "ls -l \| wc -l"
    f 'ls -l | wc -l'
    f 'ls -l \| wc -l'
    ls: impossible d'accéder à |: Aucun fichier ou dossier de ce type
    ls: impossible d'accéder à wc: Aucun fichier ou dossier de ce type
    coucou
    Je ne sais comment faire.

    Avez vous une idée ?

    Merci d'avance.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Salut
    Faut que tu fournisses à f() le résultat de ls -l | wc -l, tout comme tu pourrais lui fournir le résultat de toute autre commande. Donc faut que ls -l | wc -l soit exécuté en sous-shell...

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f $(ls -l | wc -l)
    f `ls -l | wc -l`
    A+
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Invité
    Invité(e)
    Par défaut
    Quelle est la meilleure méthode à utiliser entre le dollar et le quote pour remplacer la commande par le résultat? C'est pour ma culture générale du shell ^_^

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Beginner.j Voir le message
    Quelle est la meilleure méthode à utiliser entre le dollar et le quote pour remplacer la commande par le résultat? C'est pour ma culture générale du shell ^_^
    Salut
    Les backquotes sont le standard Bourne Shell. Le $() a été amené avec les améliorations du Bourne Again Shell.
    Donc si tu écris du shell sur (ou pour) de vieux Unix qui n'ont pas bash, tu devras te conformer au standard.

    Le $() ; en dehors d'être aussi plus visible, est aussi plus utile pour imbriquer des sous-sous shell

    Exemple: La factorielle récursive où tu programmes n * fact(n-1)
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    fact()
    {
        if test $1 -lt 2; then
            echo 1
            return
        fi
        expr $1 \* $(fact $(expr $1 - 1))
    }
    fact 5

    Si tu dois l'écrire en Bourne Shell avec les backquotes, soit tu passes par une variable intermédiaire...
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    fact()
    {
        if test $1 -lt 2; then
            echo 1
            return
        fi
     
        tmp=`expr $1 - 1`
        expr $1 \* `fact $tmp`
    }
    fact 7

    Soit tu devras protéger les backquotes inférieures par un backslash
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fact()
    {
        if test $1 -lt 2; then
            echo 1
            return
        fi
     
        expr $1 \* `fact \`expr $1 - 1\``
    }
    fact 9
    Et s'il y a encore un sous-sous niveau tu devras alors mettre des backslash eux-mêmes protégés par des backslash et toujours ensuite 2 fois le nb e backslashes précédents + 1 ce qui devient vite illisible
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    result=`commande1 \`commande2 \\\`commande3 \\\\\\\`commande4\\\\\\\`\\\`\``

    Alors qu'avec le dollar...
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    result=$(commande1 $(commande2 $(commande3 $commande4)))

    Ce sont les seules différences que je vois à l'une ou l'autre méthode. Mais sinon rien question perfos...

    Citation Envoyé par SmallFitz Voir le message
    Ma fonction f est en fait une fonction qui va me permettre de chronométrer le temps
    d'exécution de la commande que je lui passe en paramètre.
    Pour cela elle utilise time et exécute 10.000 fois la commande.
    Je compte comparer ainsi diverses commandes, pour savoir laquelle je dois utiliser.
    Alors oui, je pourrai me passer de cette fonction, et le faire à le répéter à chaque fois à la main... C'est juste moche.
    A chaud (sans tester) je penserais à eval permettant de transformer une chaine en instruction shell

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    f()
    {
        eval $*
    }
    f "ls -l | wc -l"
    Mais (en dehors de me prendre la main virtuelle de N_Bah dans la tronche virtuelle de mon égo), je ne sais pas trop comment eval va gérer le pipe...

    Citation Envoyé par SmallFitz Voir le message
    Je débute en bash,
    Tu es doué pour un débutant. Tes premiers essais étaient très bien pensés...

    Citation Envoyé par SmallFitz Voir le message
    Comme vous le voyez la sécurité je m'en tamponne un peu... =P
    C'est mal. On commence par prendre de mauvaises habitudes puis plus tard quand on se met à faire des choses plus sérieuses...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 653
    Par défaut
    utilise des fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    f() { $*;}
    ff() { ls $HOME | wc- l;}
    f ff
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Membre confirmé
    Inscrit en
    Mars 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2010
    Messages : 74
    Par défaut
    Alors reprenons.

    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
    ls -l | wc -l
    40
     
    function f { $*; }
     
    f ls -l | wc -l
    40
     
    function f2 { echo "$FUNCNAME reçoit $# paramètre(s)."; $*; }
    f2 ls -l | wc -l
    41
     
    f2 "ls -l | wc -l"
    f2 reçoit 1 paramètre(s).
    ls: impossible d'accéder à |: Aucun fichier ou dossier de ce type
    ls: impossible d'accéder à wc: Aucun fichier ou dossier de ce type
     
    function f3 { echo "$FUNCNAME reçoit $# paramètre(s) : $*"; eval $*; }
    f3 "ls -l | wc -l"
    f3 reçoit 1 paramètre(s) : ls -l | wc -l
    40
     
    function f_commande { ls -l | wc -l; }
    f3 f_commande
    f3 reçoit 1 paramètre(s) : f_commande
    40
     
    function f4 { echo "$FUNCNAME reçoit $# paramètre(s) : $*"; $*; }
    f4 f_commande
    f4 reçoit 1 paramètre(s) : f_commande
    40
    Je pense donc utiliser eval (évite de faire appel à une fonction à chaque tour de boucle).
    Quoique, qu'est-ce qui est le plus rapide : eval ou l'appel de fonction ?
    Ahah encore un truc à chronométrer

    J'aurais découvert le mot clef eval, et je vois désormais les fonctions d'un oeil nouveau.

    Merci beaucoup à vous deux ! =)

  7. #7
    Membre confirmé
    Inscrit en
    Mars 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2010
    Messages : 74
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Salut
    Faut que tu fournisses à f() le résultat de ls -l | wc -l, tout comme tu pourrais lui fournir le résultat de toute autre commande. Donc faut que ls -l | wc -l soit exécuté en sous-shell...

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f $(ls -l | wc -l)
    f `ls -l | wc -l`
    A+
    Merci pour ta réponse !

    Malheureusement, ce n'est pas ce que je souhaite faire =P
    Je voudrais que les paramètres que je lui envoie soient exécuté à un certain moment
    DANS la fonction.
    J'aimerais fournir à f une chaine de caractère composée d'un pipe.
    Puis que f appelle cette chaine de caractère pour pouvoir exécuter tout ce qu'elle contient.

    Ou est-ce impossible ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 653
    Par défaut
    Bonjour,

    je vais te le dire gentiment : par souci de sécurité, ce n'est pas souhaitable.

    expose plus en détail la raison pour laquelle tu penses devoir faire ainsi, on cherchera une solution plus sûre.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Membre confirmé
    Inscrit en
    Mars 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2010
    Messages : 74
    Par défaut
    Merci de me le dire gentiment !

    Ma fonction f est en fait une fonction qui va me permettre de chronométrer le temps
    d'exécution de la commande que je lui passe en paramètre.
    Pour cela elle utilise time et exécute 10.000 fois la commande.
    Je compte comparer ainsi diverses commandes, pour savoir laquelle je dois utiliser.
    Ca peut paraitre un peu pointu, mais c'est pourtant purement par curiosité.
    Je débute en bash, mais je suis en vac et j'ai décidé de faire ces tests...
    Alors oui, je pourrai me passer de cette fonction, et le faire à le répéter à chaque fois à la main... C'est juste moche.

    Comme vous le voyez la sécurité je m'en tamponne un peu... =P

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 02/02/2007, 16h00
  2. Envoyer un paramètre à une fonction.
    Par Squalthor dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/10/2006, 17h40
  3. Passage de paramètre à une fonction dans un G_CALLBACK
    Par Dimitri_87 dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 15/09/2006, 11h04
  4. [PL/SQL] : Passage de paramètres à une fonction
    Par dcollart dans le forum Oracle
    Réponses: 5
    Dernier message: 13/07/2006, 10h17
  5. [VBA] Envoyer un listBox en paramètre à une fonction
    Par kissmytoe dans le forum Access
    Réponses: 8
    Dernier message: 13/03/2006, 20h28

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