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 :

exécuter des commandes complexes dans un script bash


Sujet :

Shell et commandes GNU

  1. #1
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut exécuter des commandes complexes dans un script bash
    Bonjour,

    J'ai écrit une fonction[1] bash qui :
    • affiche le nom de la commande à lancer
    • lance la commande
    • affiche un message pour dire si la commande a réussi ou échoué


    Elle s'utilise comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COMMAND="sleep 1"
    execcmd
    COMMAND="echo toto  tata   tutu"
    execcmd
    COMMAND="sudo iwconfig ra0 essid \"Wi-Fi De Chez Moi\""
    execcmd
    Le problème c'est que quand la commande est complexe, il arrive parfois que la commande ne soit pas correctement exécutée.

    Dans mon exemple ci-dessus, je commence par appeler sleep (pour faire une pause de 1 seconde), puis j'appelle echo (pour afficher du texte) et enfin j'appelle iwconfig pour changer l'ESSID de ma carte Wi-Fi.

    Les deux premières commandes passent bien car elles sont simples, mais la 3ème pose problème.

    Regardez par vous même le résultat dans la console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ ./execcmd.sh 
    executing the 'sleep 1' command... Done.
    executing the 'echo toto  tata   tutu' command... toto tata tutu
    Done.
    executing the 'sudo iwconfig ra0 essid "Wi-Fi De Chez Moi"' command... iwconfig: unknown command "De"
    Failure.
    Donc ma fonction ne marche pas à tous les coups...
    Est-ce que vous savez ce que je dois changer dans le code de ma fonction ?

    Merci.

    [1]
    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
    #!/bin/bash
    VERBOSE=1
    QUIET=0
    function execcmd()
    {
    echo -n "executing the '${COMMAND}' command... "
    if test ${VERBOSE} -eq 0; then
    	${COMMAND} 1>/dev/null 2>&1
    	else
    		${COMMAND}
    fi
    if test $? -ne 0 -a ${QUIET} -eq 0; then
    	echo "Failure."
    	exit 1
    	else
    		echo "Done."
    fi
    }

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

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

    }Les deux premières commandes passent bien car elles sont simples, mais la 3ème pose problème.
    c'est pourquoi il est recommandé de na pas mettre des commandes complexes dans une variables, mais d'utiliser une fonction.

    à part ça :
    • function et () sont redondants.
    • les variables doivent toujours être mises entre guillemets, a fortiori dans des tests.
    • dans le deuxième if, $? va retourné le code d'erreur du premier if, et pas celui de la commande.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut
    Merci pour les petits conseils à la fin je corrigerai ça après avoir corrigé mon problème principal.

    Par contre au niveau du problème principal, je n'ai pas bien compris la solution.
    Je dois remplacer ma variable COMMAND par une fonction c'est ça?
    Je ne vois pas bien comment une fonction peut remplacer le rôle de ma variable...

    Tu peux me montrer un exemple?

  4. #4
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    A priori on dirait que tu essayes de reproduire le comportement de eval...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [idriss@hp-dv6:~]$ COMMAND="echo \"salut\""
    [idriss@hp-dv6:~]$ eval $COMMAND
    salut
    [idriss@hp-dv6:~]$
    Quel est ton véritable besoin ?

    Cordialement,
    Idriss

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    effectivement, dans ton cas, une fonction n'y fera rien.
    utilise un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    command=( sudo iwconfig ra0 essid "Wi-Fi De Chez Moi" )
    printf 'j'\''exécute la commande : %s...' "${command[@]}"
    ${command[@]}
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    La meilleure solution à mon avis c'est de passer la commande à exécuter en argument. Quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    execcmd () {
        echo -n "executing the '$@' command... "
        "$@"
        echo
    }
     
    execcmd sleep 1
    execcmd echo "toto  tata   tutu"
    execcmd sudo iwconfig ra0 essid "Wi-Fi De Chez Moi"
    Si tu passes par une variable comme tu essaies de le faire, tous les arguments sont mis à plat et tu perds la notion de groupage (i.e. "toto tata tutu" est un seul "mot").

  7. #7
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut
    matafan> Ta solution fonctionne Par contre, il faut absolument entourer le $@ par des guillemets ("$@") comme tu as fait car sinon, le problème est toujours présent. Merci pour ta solution.

    N_BaH> Je n'ai pas essayé cette solution avec un tableau puisque la solution de matafan semble fonctionner à merveilles... Mais merci pour l'astuce.

    ok.Idriss> Ce que j'essaie de faire c'est de créer une fonction qui fait ce que j'explique ci-dessus car je trouve ça intéressant dans un script de faire afficher à l'utilisateur les commandes qui sont appelées avant de réellement les appeler (ça donne un renseignement supplémentaire à l'utilisateur du script). Ainsi, on a une meilleure vision de ce qui se passe. Je n'essaie pas de reproduire le comportement de eval puisque eval n'affiche pas le nom de la commande avant que la commande soit lancée.

    Merci c'est résolu (mais vous pouvez toujours proposer des solutions alternatives si vous avez).

  8. #8
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonsoir.

    Bah dans ce cas une simple fonction comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    executeCmd(){
        echo -n "executing the $1 command... "
        eval $1
    }
     
    executeCmd "ls -la /usr/bin"
    Ferait la même chose, non ?
    Eh oui on a le droit de ré-utiliser ce qui est déjà fait, surtout si c'est qu'une histoire d'affichage en plus...

    Idriss

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut


    eval is evil. !
    (eval c'est mal !)

    dans le cas présent, ça ne fera pas beaucoup de différence, puisque YuGiOhJCJ passe des commandes,
    mais ça demeure une solution de facilité dangereuse.

    alors, le proposer deux fois dans le même sujet...
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Pardon grand maître, ça ne se reproduira plus

    [Mais bon dans le cas présent, ça ne changerait pas grand chose comme tu dit ]

  11. #11
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Non ce n'est pas pareil, avec eval tu as toujours le même problème que tu perds le groupage corrects des mots en arguments.

    Ca va un peu mieux si tu met le $1 entre double quotes (eval "$1"), mais tu es toujours obligé d'escaper correctement la chaine que tu passes en argument à executeCmd.

    Avec "$@" tu n'as pas ces soucis, et le groupage des mots en arguments est conservé.

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

Discussions similaires

  1. Exécuter une commande sudo dans un script shell
    Par lodacom dans le forum Shell et commandes GNU
    Réponses: 11
    Dernier message: 24/04/2014, 13h37
  2. Impossible d'exécuter une commande avec su dans un script bash
    Par koshieDotFr dans le forum Shell et commandes GNU
    Réponses: 8
    Dernier message: 18/12/2012, 13h47
  3. Récupérer des données mysql dans un script bash
    Par xunil2003 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 28/07/2012, 20h33
  4. Réponses: 6
    Dernier message: 07/05/2008, 13h54
  5. Réponses: 1
    Dernier message: 14/03/2007, 15h56

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