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 :

Revue de code bash


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2003
    Messages : 304
    Par défaut Revue de code bash
    Salut à tous !

    Si quelqu'un veut discuter du code ci-dessous

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
     
    #-*-shell-script-*-
     
    export NOTES_TXT=~/NOTES/TXT/
    export NOTES_LOG=~/NOTES/LOG/
     
    #        /\          /\          /\
    #     /\//\\/\    /\//\\/\    /\//\\/\
    #  /\//\\\///\\/\//\\\///\\/\//\\\///\\/\
    # //\\\//\/\\///\\\//\/\\///\\\//\/\\///\\
    # \\//\/                            \/\\//
    #  \/                                  \/
    #  /\                                  /\
    # //\\      The search function       //\\
    # \\//                                \\//
    #  \/                                  \/
    #  /\                                  /\
    # //\\/\                            /\//\\
    # \\///\\/\//\\\///\\/\//\\\///\\/\//\\\//
    #  \/\\///\\\//\/\\///\\\//\/\\///\\\//\/
    #     \/\\//\/    \/\\//\/    \/\\//\/
    #        \/          \/          \/
     
    function notes.search {
        # examples
        # notes.search --log --newer-than 30 -E "(streaming.*TDA|TDA.*streaming)"
        # notes.search --txt -F --headings "nextcloud"
        # notes.search --all -F "streaming"
        # notes.search --all --newer-than 30 -F "streaming"
        # notes.search --all --recent "streaming"
     
        local search_dirs="$NOTES_TXT"
        local find_recent
        local headings_prefix
        local pattern
        local grep_opts grep_opts_debug
        local ls_opts="-t"
     
        # echo "function args $@"
        TEMP=$(getopt -uo EFr -l all,log,txt,LOG,TXT,newer-than:,headings,recent,all -- $@)
        # echo "TEMP $TEMP"
        set -- $TEMP
        while (($# > 0))
        do
    	# echo "looking at $1"
    	case "$1" in
    	    --all)
    		search_dirs="$NOTES_TXT $NOTES_LOG"
    		;;
     
    	    --log|--LOG)
    		search_dirs="$NOTES_LOG"
    		;;
     
    	    --txt|--TXT)
    	        search_dirs="$NOTES_TXT"
    		;;
     
    	    --newer-than)
    		shift
    		find_recent="-mtime -$1"
    		;;
     
    	    --heading?)
    		headings_prefix="^\*.* "
    		;;
     
    	    --recent)
    		find_recent="-mtime 30"
    		;;
     
    	    -E)
    		grep_opts="-E"
    		;;
     
    	    -F)
    		grep_opts="-F"
    		;;
    	    -r)
    		ls_opts="-rt"
    		;;
    	    --)
    		# echo "parsing -- : arg before shift $1"
    		shift
    		# echo "parsing -- : arg after shift $1"
    		pattern="$*"
    		# echo "parsing -- : pattern is $pattern"
    		;;
    	esac
    	shift 
        done
     
     
        [[ -z $pattern ]] && (echo "no pattern specified"; notes.search.usage; return 1)
        [[ -n $grep_opts ]] && grep_opts_debug="with the $grep_opts option"
        > /tmp/notes.search.results.colors
        find $search_dirs -not -name "*~" -type f $find_recent | xargs ls "$ls_opts" | while read file
        do
    	grep --color=always -H -n -i $grep_opts "$headings_prefix$pattern" "$file"  | tee -a /tmp/notes.search.results.colors
        done    
     
        pretty.colors.remove /tmp/notes.search.results.colors > /tmp/notes.search.results
    }
     
    function notes.search.usage {
        echo "usage : notes.search.new <options> <pattern>"
        echo "options :"
        echo "                  -E : regex search"
        echo "                  -F : fast search"
        echo "                  -r : reverse order (newer first)"
        echo "               --all : search all notes"
        echo "               --txt : search text notes only (default)"
        echo "               --log : search logs only "
        echo " --newer-than <days> : useful with --log; search only in files that were modified in the last <days> days"
        echo "            --recent : useful with --log; search only in files that were modified in the last 30 days"
        echo "          --headings : search only in headings"
    }
    particulièrement :

    - comment gérer les arguments avec espace quand on utilise getopt
    - si au contraire je devrais réécrire le traitement des arguments en ligne de commande à la mano.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 672
    Par défaut
    d'abord,
    il faut toujours mettre les Développement des paramètres entre guillemets. TOUJOURS !
    à moins de savoir pourquoi.
    puis,
    pourquoi pas while getopt...; do ...; done ?
    et
    ON N'UTILISE PAS ls DANS UN SCRIPT !!!
    je te l'ai déjà dit ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$search_dirs" -not -name '*~' -type f $find_recent -exec grep --color=always -H -n -i $grep_opts "$headings_prefix$pattern" \; >>/tmp/notes.search.results.colors
    les options de commandes (-mtime, par exemple) seront mieux traitées dans un tableau que dans une variable.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre expérimenté
    Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2003
    Messages : 304
    Par défaut
    Merci N_BaH pour tes retours toujours aussi précieux !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while getopt...; do ...; done ?
    Je ne connaissais pas cette syntaxe.
    En fait, c'est la première fois que j'utilise getopt.
    J'ai suivi l'exemple livré avec dans /usr/share/doc/util-linux/examples/getopt-parse.bash
    Le code ressemble à ça :

    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
     
    # Note that we use `"$@"' to let each command-line parameter expand to a
    # separate word. The quotes around `$@' are essential!
    # We need TEMP as the `eval set --' would nuke the return value of getopt.
    TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
         -n 'example.bash' -- "$@"`
     
    if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
     
    # Note the quotes around `$TEMP': they are essential!
    eval set -- "$TEMP"
     
    while true ; do
    [...]
    done
    echo "Remaining arguments:"
    for arg do echo '--> '"\`$arg'" ; done
    J'ai pas trop compris pourquoi l'usage de eval,
    ni pourquoi il restait des arguments à traiter après la boucle while...
    Donc j'ai adapté à ma sauce.
    Je prend note pour essayer cette syntaxe.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$search_dirs" -not -name '*~' -type f $find_recent -exec grep --color=always -H -n -i $grep_opts "$headings_prefix$pattern" \; >>/tmp/notes.search.results.colors
    Concernant l'usage de ls, tant que je ne suis pas menacé de mort...
    c'est parce que j'aimerais parcourir les fichiers dans l'ordre anti-chronologique
    (plus récent d'abord) si j'appelle ma fonction avec l'option -r
    (ça va appeler ls -rt)

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 672
    Par défaut
    pour ls, c'est une démarche pédagogique (ce n'est pas une lubie ) : laisser traîner ce genre de commandes sur les forums, c'est laisser croire aux futurs lecteurs que c'est une bonne pratique, alors qu'elle ne l'est pas.
    après, on va encore devoir expliquer pourquoi tel fichier n'est pas traité, parce qu'il contient un espace, un alinéa, ou autre.
    donc, dans ton cas, puisqu'il faut trier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    find ... -printf '%...\0' \
        | sort -z -k... \
        | cut -z -d ' ' -f 2- \
        |  xargs -0 -I {} <command> {}
    c'est un peu plus long, mais c'est 100% sûr.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 848
    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 848
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par yacinechaouche Voir le message
    Si quelqu'un veut discuter du code ci-dessous...
    Pourquoi ces "export" en début de script? Tes variables ont-elles besoin d'être connues par des sous-shells? Parce que c'est là le rôle de cette commande.

    Citation Envoyé par yacinechaouche Voir le message
    - comment gérer les arguments avec espace quand on utilise getopt
    Tu n'as pas à le gérer, c'est à l'appelant de s'en occuper. Il sait que ton argument attend un mot, s'il veut lui passer deux mots en un il doit encadrer ces deux mots avec des guillemets.
    C'est d'ailleurs pareil pour toi. Tu veux créer le dossier "mon truc" tu devras taper explicitement mkdir "mon truc".
    Et pareil, dans ton script, tu veux traiter une variable censée contenir une string, tu dois toujours encadrer ta variable de double guillemets au cas où la string contenue dans cette variable contiendrait un espace (toutefois, soyons intelligents, si la variable est elle-même dans une string plus englobante, c'est la string entière qu'on encadre de guillemets et la variable reste telle-quelle => exemple echo "Mon login est $LOGNAME" et non pas echo Mon login est "$LOGNAME")

    Citation Envoyé par yacinechaouche Voir le message
    - si au contraire je devrais réécrire le traitement des arguments en ligne de commande à la mano.
    Oh là là, t'as pas fini. Si getopt existe, c'est pour une bonne raison !!!

    Citation Envoyé par yacinechaouche Voir le message
    Concernant l'usage de ls, tant que je ne suis pas menacé de mort...
    T'es fou !!! Dire ça à N_BaH
    Il serait capable de venir te trouver dans tes rêves, comme Freddy, juste pour te hurler "on n'utilise pas ls dans des scripts " (il l'a déjà fait avec moi )
    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]

Discussions similaires

  1. Outil pour la revue de code
    Par FABFAB125 dans le forum Outils
    Réponses: 7
    Dernier message: 25/11/2007, 10h35
  2. Outils de revue de code
    Par grabriel dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 22/08/2007, 11h56
  3. Outils de revue de code
    Par YAMKI dans le forum Qualimétrie
    Réponses: 2
    Dernier message: 15/02/2006, 12h29
  4. [Conseil] revue de code
    Par allstar dans le forum Langage
    Réponses: 2
    Dernier message: 09/11/2005, 11h02
  5. [Revue de code] Quels outils pour de grosses applis?
    Par franckR dans le forum Choisir un environnement de développement
    Réponses: 1
    Dernier message: 21/03/2004, 10h03

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