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 :

Changement de comportement du script bash si argument fourni


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut Changement de comportement du script bash si argument fourni
    Bonsoir à toutes et à tous,

    J'ai un script bash qui tente de retrouver les versions de PERL installées sur un station Linux (Fedora dans mon cas).
    Si je lance le script SANS argument, le fichier test.txt contient bien l'ensemble des versions PERL installées sur mon ordinateur. En revanche, si je lance le script AVEC un argument, le fichier test.txt est vide!

    Voici le script:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/bin/bash
    cat /dev/null > test.txt
    for __ENS_LOOPI__ in `echo $PATH | sed 's/:/ /g'`; do
    	ls -B --color='never' -w 1 ${__ENS_LOOPI__}/perl* 2>/dev/null | grep -i "perl[0-9\.]$*" | sed 's#[*@~]$##' 1>> test.txt
    done


    Une idée ?

    Merci par avance,
    Mickaël

  2. #2
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Bonjour,

    La dépendance se situe sur le "grep":
    Sans paramêtre, cela donne:
    Avec un paramêtre (exemple: toto):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -i "perl[0-9\.]toto"
    Cordialement.
    Cordialement.

  3. #3
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find ${PATH//:/ } -type f -regex '.*perl[0-9].*' -printf '%f\n'
    perl5.14.2
    moins il y a de commandes, moins c'est facile de se tromper.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    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
    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    La dépendance se situe sur le "grep":
    Farpaitement!

    "$*" s'expanse en tous les arguments.

    Que voulais-tu dire avec $* dans grep -i "perl[0-9\.]$*" ???

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Bonsoir,

    Avant tout, merci pour vos excellentes remarques qui m'ont permis de trouver la solution!

    @Disedorgue: tu as visé juste!

    @N_Bah: En effet, moins il y a de commandes, moins il y a d'erreurs. Cependant, moins il y a de commandes, moins c'est portable!
    En général, l'intérêt d'avoir de nombreuses commandes repose sur la portabilité, en utilisant des commandes aussi basiques que possibles.
    Dans ton cas, par exemple, si quelqu'un a (Je ne sais pour quelle raison) dans sa variable d'environnement $PATH un chemin non pertinent, alors ta commande retournera quelquechose du genre "/chemin/non/pertinent: No such file or directory"

    @jack-ft: Simple erreur de typo. Ca devrait être "*$" afin de préciser que l'élément doit terminer la ligne. Le fait d'avoir fait cette erreur de typo donne tout son sens aux résultats que j'obtenais. Par exemple, /usr/bin/perl était sélectionné alors qu'il ne devait pas l'être!

    En conclusion, afin que les éléments suivants soient sélectionnés:
    /usr/bin/perl5.10.1
    /usr/bin/perl5.8.8

    Mais pas les suivants:
    /usr/bin/perl
    /usr/bin/perl5.10.1blabla
    /usr/bin/perlbug

    La solution est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #!/bin/bash
    cat /dev/null > test.txt
    for __ENS_LOOPI__ in `echo $PATH | sed 's/:/ /g'`; do
    	ls -B --color='never' -w 1 ${__ENS_LOOPI__}/perl* 2>/dev/null | grep -i "perl[0-9][0-9\.]*$" | sed 's#[*@~]$##' 1>> test.txt
    done
    Encore merci,
    Mickaël

  6. #6
    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
    Citation Envoyé par mkrzemin
    Dans ton cas, par exemple, si quelqu'un a (Je ne sais pour quelle raison) dans sa variable d'environnement $PATH un chemin non pertinent, alors ta commande retournera quelquechose du genre "/chemin/non/pertinent: No such file or directory"
    cette remarque s'applique également à ton code.

    pour info :
    sed n'est pas totalement portable.
    pareil pour grep, et ls.

    l'uuoc, lui, est parfaitement portable.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    cette remarque s'applique également à ton code.

    pour info :
    sed n'est pas totalement portable.
    pareil pour grep, et ls.

    l'uuoc, lui, est parfaitement portable.
    Oui oui, tout à fait, et c'est pourquoi au début de mon code, je vérifie que ces fonctions (qui sont basiques dans l'immense majorité des distributions Linux) sont présentes, auquel cas contraire, le programme s'arrête et avertit l'utilisateur (Non mais, ça veut utiliser mon programme et ça n'a même pas ces fonctions de base! ).
    Pour ce faire, une simple approche comme la suivante est suffisante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    __ENS_BASIC_CMDS__=( pwd head awk sed cat more grep wc dirname mkdir )
    for __ENS_LOOPI__ in ${__ENS_BASIC_CMDS__[@]}; do
    	type -P $__ENS_LOOPI__ 2>/dev/null  && continue  || { print "The $__ENS_LOOPI__ command cannot be found on this station. The installation will be aborting\n"; exit 1; }
    done
    Sinon, pour l'uuoc, c'est une excellente remarque. Et en effet, on devrait y prêter plus attention. Dans mon code, je devrais plutôt utiliser un touch ou un print, mais c'est devenu presqu'un réflexe que de créer un fichier vide de cette manière là!

    Mickaël

  8. #8
    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
    > fichierÀvider #ou à créer suffit.

    pwd est une commande intégrée de bash, mais pas print. t'es passé à ksh ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    pwd est une commande intégrée de bash, mais pas print. t'es passé à ksh ?
    Houlà! En effet, il faudrait que je fasse plus de copier/coller au lieu de recopier les lignes avec des erreurs. Il s'agit de printf qui est une commande "Built-in".

    Par contre, tu veux dire quoi par
    Citation Envoyé par N_BaH Voir le message
    > fichierÀvider #ou à créer suffit.
    ?

    Mickaël

  10. #10
    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
    Citation Envoyé par mkrzemin
    Par contre, tu veux dire quoi par
    Citation Envoyé par N_BaH
    > fichierÀvider #ou à créer suffit.
    ?
    Citation Envoyé par man BASH /Redirection de sortie
    [...]Si le fichier n'existe pas, il est créé. S'il existait déjà, sa taille est réduite à zéro.
    il ne faut pas confondre printf avec echo.
    qui peut le plus peut le moins, cependant printf est mieux utilisé pour le formatage des données, que pour leur simple affichage.
    de la même manière, echo ne devrait pas être utilisé lorsqu'il faut afficher des données sous un certain format.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    il ne faut pas confondre printf avec echo.
    qui peut le plus peut le moins, cependant printf est mieux utilisé pour le formatage des données, que pour leur simple affichage.
    de la même manière, echo ne devrait pas être utilisé lorsqu'il faut afficher des données sous un certain format.
    Entièrement d'accord avec toi!
    Il y a de grandes différences entre les deux, ne serait-ce que le "exit status". Avec printf aussi, il est plus pratique de gérer les caractères spéciaux (avec echo, sur certaines stations, il arrive que les flags qui permettent d'interpréter les caractères spéciaux ne fonctionnent pas).
    J'ai juste une préférence pour le printf car je suis un grand fan du langage C!
    Enfin, pour echo, je serai un peu plus strict que toi et je dirais qu'il ne PEUT pas être utilisé pour afficher des données sous un certain format!

    Mickaël

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

Discussions similaires

  1. Script bash - boucle lecture arguments
    Par jffskyx dans le forum Shell et commandes GNU
    Réponses: 11
    Dernier message: 16/09/2011, 08h13
  2. Requête POST dans un script bash
    Par desperado dans le forum Linux
    Réponses: 4
    Dernier message: 11/12/2007, 22h38
  3. Script bash : Pb avec sed
    Par fred64 dans le forum Linux
    Réponses: 3
    Dernier message: 19/08/2005, 11h24
  4. Scripts bash : requêtes sql
    Par milka dans le forum Linux
    Réponses: 3
    Dernier message: 17/08/2005, 10h59
  5. Problème script Bash
    Par Sphost dans le forum Linux
    Réponses: 10
    Dernier message: 26/07/2005, 09h56

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