Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/04/2011, à 08:12

nira83

Bash - verification de code

Bonjour ,
Pour remplir les conditions du cahier des charges de mon stage , j'ai du me mettre au bash. J'ai réalisé deux scripts assez important en terme de taille mais je n'avais aucunes connaissances de ce langages .
Pouvez vous me dire si des choses vous choquent dans le code ? Des erreurs syntaxiques ou quoi...
Les codes marchent parfaitement et réalisent les actions souhaitées. Pour résumer leurs fonctions :
On a un client et un serveur . Le serveur reçoit des paquets en socket normal ou socket raw et je mesure la quantité de CPU nécessaire. De même le client lui envoi au serveur .

On peut spécifier différents arguments qui doivent être identique coté server/client.

EDIT AVEC DIVERSES MODIFICATIONS

Application coté Client

#!/bin/bash

ad_dst=0
network=0
TIME=1
while getopts NRsna:A:u:w:m:M:S:r:P:I:x: option
do
    case $option in
    N)     [ -z "$commande" ] && { commande="NORMAL" ; } || { echo "N or R, not NR" ; exit ; }  ;;
    R)     [ -z "$commande" ] && { commande="RAW" ; } || { echo "R or N not RN" ; exit ; }  ;;
    s)     [ -z "$MODE" ] && { MODE="SIZE" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    n)     [ -z "$MODE" ] && { MODE="NUMBER" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    a)     [ -z "$MODE" ] && { MODE="AVERAGE" ; MAX=$OPTARG ; } || { echo "Only s or n or a" ; exit ; }  ;;
    A)    TIME=$OPTARG     ;;
    m)    MIN=$OPTARG     ;;
    M)    MAX=$OPTARG     ;;
    S)    STEP=$OPTARG     ;;
    r)    FILE=$OPTARG     ;;
    I)    network=$OPTARG    ;;
    P)    ad_dst=$OPTARG    ;;
    u)    MIN=$OPTARG     ;;
    w)    STEP=$OPTARG    ;;
    x)    X=$OPTARG    ;;
    esac
done

#If no arg obg so
if [ "$MODE" = "AVERAGE" ]
then
    if [ -z "$MIN" ]
    then
        MIN=1000
    fi
    if [ -z "$STEP" ]
    then
        STEP=500
    fi
elif [ "$MODE" = "SIZE" ] || [ "$MODE" = "NUMBER" ]  
then
    if [ -z "$MIN" ] && [ -z "$MAX" ] && [ -z "$STEP" ]
    then
        MIN=100
        MAX=1000  
        STEP=10
    elif [ -z "$MIN" ] && [ -z "$MAX" ] && [ -n "$STEP"  ]
    then
        MIN=$STEP
        let "MAX = 100 * STEP"
    elif [ -z "$MIN" ] && [ -z "$STEP" ] && [ -n "$MAX" ]
    then
        let "STEP = MAX / 100"
        let "MIN = STEP"
    elif [ -z "$MIN" ] && [ -n "$STEP" ] && [ -n "$MAX" ]
    then
        let "MIN = STEP"
    elif [ -z "$MAX" ] && [ -n "$STEP" ] && [ -n "$MIN" ]
    then
        let "MAX = 100 * STEP"
    elif [ -z "$MAX" ] && [ -z "$STEP"  ] && [ -n "$MIN"  ] 
    then
        STEP=$MIN
        let "MAX = 100 * STEP"
    elif [ -z "$STEP" ] && [ -n "$MIN" ] && [ -n "$MAX" ]
    then
        STEP=10
    fi
    if [ -z "$X" ]
    then
        X=1000
    fi
    if [ -z "$FILE" ]
    then    
        i=0
        if [ "$MODE" = "SIZE" ]
        then
            FILE=Cli_"$commande"_"$MODE"_$i
            while [ -e $FILE.siz ]
            do
            let "i = i + 1"
            FILE=Cli_"$commande"_"$MODE"_$i
        done    

        elif [ "$MODE" = "NUMBER" ]
        then
            FILE=Cli_"$commande"_"$MODE"_$i
            while [ -e $FILE.num ]
            do
            let "i = i + 1"
            FILE=Cli_"$commande"_"$MODE"_$i
        done                    
        fi
    fi
else
    echo "Error, You don't choose MODE"
    exit
fi
#___________

if [ "$MODE" = "SIZE" ]
then
    echo -e "\nYou take SIZE mode with $commande socket"
    echo "You send on $network and $ad_dst"
    echo -e "You send :\n- MIN = $MIN\n- STEP = $STEP\n- MAX = $MAX "
    echo "Number of packet = $X"
    echo -e "Your name save : $FILE.siz\n" 

elif [ "$MODE" = "NUMBER" ]
then
        echo -e "\nYou take NUMBER mode with $commande socket"
        echo "You send on $network and $ad_dst"
        echo -e "You send :\n- MIN = $MIN\n- STEP = $STEP\n- MAX = $MAX "
        echo "Size of packet = $X"
        echo -e "Your name save : $FILE.num\n" 
elif [ "$MODE" = "AVERAGE" ]
then
    echo -e "\nYou take AVERAGE mode with $commande socket"
        echo "You send on $network and $ad_dst"
        echo -e "You send :\n- Number of packet = $MIN\n- Size of packet = $STEP\n- Time = $MAX\n"
fi

if [ "$commande" = "RAW" ]
then
        commande=./client_send_raw


elif [ "$commande" = "NORMAL" ]
then
        commande=./client
fi

if [ "$MODE" = "SIZE" ] 
then
nbline=0
# for ((i=MIN;i<=MAX;i+=STEP))
for i in `seq $MIN $STEP $MAX`;
do
    for t in `seq 1 1 $TIME`;
    do
    (perf stat $commande $ad_dst $network $X $i 2>&1) | tee -a $FILE.txt
    let "nbline += 1"
    sleep 2
    done
done

elif [ "$MODE" = "NUMBER" ]
then
nbline=0
for i in `seq $MIN $STEP $MAX`;
do
    for t in `seq 1 1 $TIME`;
    do
    (perf stat $commande $ad_dst $network $i $X 2>&1) | tee -a $FILE.txt
    let "nbline += 1"
    sleep 2
    done
done

elif [ "$MODE" = "AVERAGE" ]
then
FILE=tmp
for i in `seq 1 1 $MAX`;
do
    (perf stat $commande $ad_dst $network $MIN $STEP 2>&1) | tee -a $FILE.txt
    sleep 2
done

else
    echo -e "Bad Enter"
    exit
fi

awk ' { gsub(/\./, ",") } ; /Mb\/s/ { mb=$3 } ; /CPUs/ { print $1 "\t" $4 "\t" mb } ' $FILE.txt > Cpu_$FILE.xls

rm *$FILE.txt
#Now CPU , Clk , Mb/s in colonne.


if [ "$MODE" = "SIZE" ]
then
trame_size=$MIN
if [ "$commande" = "./client" ]
then
echo -e "Trame_size\tClient_clock\tClient_CPUs\tClient_Mb/s\n" > $FILE.siz
else
echo -e "Trame_size\tCliRaw_clock\tCliRaw_CPUs\tCliRaw_Mb/s\n" > $FILE.siz
fi

FLAG=1
while read -p ">>" line  
do 
       echo -e "$trame_size\t$line" >> $FILE.siz
    if [ $TIME = $FLAG ]
    then
    let "trame_size = trame_size + STEP"
        FLAG=1
    else    
        let "FLAG = FLAG + 1"
    fi
done < Cpu_$FILE.xls


elif [ "$MODE" = "NUMBER" ]
then
pkt_size=$MIN
if [ "$commande" = "./client" ]
then
echo -e "Nb_pkt\tClient_clock\tClient_CPUs\tClient_Mb/s\n" > $FILE.num
else
echo -e "Nb_pkt\tCliRaw_clock\tCliRaw_CPUs\tCliRaw_Mb/s\n" > $FILE.num
fi

FLAG=1
while read -p ">>" line  
do
       echo -e "$pkt_size\t$line" >> $FILE.num
    if [ $TIME = $FLAG ]
    then
        let "pkt_size = pkt_size + STEP"
        FLAG=1
    else    
        let "FLAG = FLAG + 1"
    fi
done < Cpu_$FILE.xls


elif [ "$MODE" = "AVERAGE" ]
then
./average Cpu_$FILE.xls $MAX
rm *$FILE

fi

line=1
let "f = TIME + line - 1"
let "nbline = nbline / TIME"
if [ "$TIME" != "1" ]
then
    for b in `seq 1 1 $nbline`;
    do    
        
        for i in `seq $line 1 $f`;
        do
            sed -n "$i"p Cpu_$FILE.xls >> Tmp_$FILE.xls
        done
        let "f = f + TIME"
        let "line = i"
        echo "$MODE packet , $MIN , $X" >> $FILE
        let "MIN = MIN + STEP"
        ./average Tmp_$FILE.xls $TIME >> $FILE.ave
        rm Tmp_$FILE.xls
    done

fi
rm Cpu_$FILE.xls
echo -e "Execution End"
echo -e "*********************************************************************"

Application coté Server

#!/bin/bash
#Send start
clear

ad_dst=0
network=0
nbline=0
FLAG=1
TIME=1
while getopts NRsna:A:u:w:m:M:S:r:P:x: option
do
    case $option in
    N)     [ -z "$commande" ] && { commande="NORMAL" ; } || { echo "N or R, not NR" ; exit ; }  ;;
    R)     [ -z "$commande" ] && { commande="RAW" ; } || { echo "R or N not RN" ; exit ; }  ;;
    s)     [ -z "$MODE" ] && { MODE="SIZE" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    n)     [ -z "$MODE" ] && { MODE="NUMBER" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    a)     [ -z "$MODE" ] && { MODE="AVERAGE" ; MAX=$OPTARG ; } || { echo "Only s or n or a" ; exit ; }  ;;
    A)    TIME=$OPTARG    ;;
    m)    MIN=$OPTARG    ;;
    M)    MAX=$OPTARG    ;;
    S)    STEP=$OPTARG    ;;
    r)    FILE=$OPTARG    ;;
    P)    network=$OPTARG    ;;
    u)    MIN=$OPTARG     ;;
    w)    STEP=$OPTARG    ;;
    esac
done

#If no arg obg so
    
if [ "$MODE" = "SIZE" ] || [ "$MODE" = "NUMBER" ]  
then
    if [ -z "$MIN" ] && [ -z "$MAX" ] && [ -z "$STEP" ]
    then
        MIN=100
        MAX=1000  
        STEP=10
    elif [ -z "$MIN" ] && [ -z "$MAX" ] && [ -n "$STEP"  ]
    then
        MIN=$STEP
        let "MAX = 100 * STEP"
    elif [ -z "$MIN" ] && [ -z "$STEP" ] && [ -n "$MAX" ]
    then
        let "STEP = MAX / 100"
        let "MIN = STEP"
    elif [ -z "$MIN" ] && [ -n "$STEP" ] && [ -n "$MAX" ]
    then
        let "MIN = STEP"
    elif [ -z "$MAX" ] && [ -n "$STEP" ] && [ -n "$MIN" ]
    then
        let "MAX = 100 * STEP"
    elif [ -z "$MAX" ] && [ -z "$STEP"  ] && [ -n "$MIN"  ] 
    then
        STEP=$MIN
        let "MAX = 100 * STEP"
    elif [ -z "$STEP" ] && [ -n "$MIN" ] && [ -n "$MAX" ]
    then
        STEP=10
    fi
    if [ -z "$mtu" ]
    then
        mtu=10000
    fi
    if [ -z "$FILE" ]
    then    
        i=0
        if [ "$MODE" = "SIZE" ]
        then
            FILE=Ser_"$commande"_"$MODE"_$i
            while [ -e $FILE.siz ]
            do
            let "i = i + 1"
            FILE=Ser_"$commande"_"$MODE"_$i
        done    

        elif [ "$MODE" = "NUMBER" ]
        then
            FILE=Ser_"$commande"_"$MODE"_$i
            while [ -e $FILE.num ]
            do
            let "i = i + 1"
            FILE=Ser_"$commande"_"$MODE"_$i
        done                    
        fi
    fi
else
    echo "Error, You don't choose MODE"
    exit
fi
#___________

if [ "$MODE" = "SIZE" ]
then
    echo -e "\nYou take SIZE mode with $commande socket."
    echo "You listen on $network."
    echo -e "You rcvd :\n- MIN = $MIN\n- STEP = $STEP\n- MAX = $MAX."
    echo -e "Your name save : $FILE.siz.\n" 

elif [ "$MODE" = "NUMBER" ]
then
        echo -e "\nYou take NUMBER mode with $commande socket."
        echo "You listen on $network."
        echo -e "You rcvd :\n- MIN = $MIN\n- STEP = $STEP\n- MAX = $MAX. "
        echo -e "Your name save : $FILE.num.\n" 

elif [ "$MODE" = "AVERAGE" ]
then
    echo -e "\nYou take AVERAGE mode with $commande socket."
        echo "You listen on $network."
        echo -e "You rcvd :\n- Time = $MAX.\n"
fi

if [ "$commande" = "RAW" ]
then
    commande=./server_listen_raw_scr

elif [ "$commande" = "NORMAL" ]
then
    commande=./server_scr
fi

if [ "$MODE" = "SIZE" ] || [ "$MODE" = "NUMBER" ]
then

echo -e "Wait connection on $network..."
for i in `seq $MIN $STEP $MAX`;
do
    for t in `seq 1 1 $TIME`;
    do
    (perf stat $commande $network 2>&1) | tee -a $FILE.txt
    let "nbline += 1"
    done
done

elif [ "$MODE" = "AVERAGE" ]
then
TIMES=$MAX
FILE=tmp

echo -e "Wait connection on $net_port..."

for i in `seq 1 1 $TIMES`;
do
    (perf stat $commande $network 2>&1) | tee -a $FILE.txt
done

fi


#Rcpt finish
awk ' { gsub(/\./, ",") } ; /Mb\/s/ { mb=$3 } ; /CPUs/ { print $1 "\t" $4 "\t" mb } ' $FILE.txt > Cpu_$FILE.xls


if [ "$MODE" = "SIZE" ]
then
    if [ $commande = "./server_scr" ]
    then
        echo -e "Size_pkt\tServer_clock\tServer_CPUs\tServer_Mb/s\n" > $FILE.siz
    elif [ $commande = "./server_listen_raw_scr" ]
    then
        echo -e "Size_pkt\tSerRaw_clock\tSerRaw_CPUs\tSerRaw_Mb/s\n" > $FILE.siz
    else
        echo -e "Bad commande"
        exit
    fi
tmp=$MIN
while read -p ">>" line
do
        echo -e "$tmp\t$line" >> $FILE.siz
        if [ $TIME = $FLAG ]
    then
        let "tmp = tmp + STEP"
        FLAG=1
    else    
        let "FLAG = FLAG + 1"
    fi
done < Cpu_$FILE.xls


elif [ "$MODE" = "NUMBER" ]
then
    if [ "$commande" = "./server_scr" ]
    then
        echo -e "Nb_pkt\tServer_clock\tServer_CPUs\tServer_Mb/s\n" > $FILE.num
    elif [ "$commande" = "./server_listen_raw_scr" ]
    then
        echo -e "Nb_pkt\tSerRaw_clock\tSerRaw_CPUs\tSerRaw_Mb/s\n" > $FILE.num
    else
        echo -e "Bad commande"
        exit
    fi
tmp=$MIN
while read -p ">>" line
do
        echo -e "$tmp\t$line" >> $FILE.num
        if [ "$TIME" = "$FLAG" ]
    then
        let "tmp = tmp + STEP"
        FLAG=1
    else    
        let "FLAG = FLAG + 1"
    fi
done < Cpu_$FILE.xls


elif [ "$MODE" = "AVERAGE" ]
then
    ./average Cpu_$FILE.xls $TIMES


else
    exit
fi 
rm $FILE.txt
line=1
let "f = TIME + line - 1"
let "nbline = nbline / TIME"
if [ "$TIME" != "1" ]
then
    for b in `seq 1 1 $nbline`;
    do    
        
        for i in `seq $line 1 $f`;
        do
            sed -n "$i"p Cpu_$FILE.xls >> Tmp_$FILE.xls
        done
        let "f = f + TIME"
        let "line = i"
        echo "$MODE packet , $MIN , $X" >> $FILE.ave
        let "MIN = MIN + STEP"
        ./average Tmp_$FILE.xls $TIME >> $FILE.ave
        rm Tmp_$FILE.xls
    done
fi
rm Cpu_$FILE.xls

Pour résumer ma demande :
Est ce que vous voyez des erreurs de syntaxes , qui n'interviennent pas au niveau du fonctionnement des applications mais qui peuvent gêner au niveau de la vitesse d'exécution ou quoi. Des trucs qui vous choquent ...etc
Les commandes que j'utilise pour faire fonctionner les applications sont de cette forme :
par exemple :
./App_Ser.sh -RnA 10 -m 100 -M 1000 -S 10 -P eth1

./App_Cli.sh -RnA 10 -m 100 -M 1000 -S 10 -P xx:xx:xx:xx:xx:xx -I eth1

Merci pour votre aide! big_smile

PS : Les scriptes appellent des fonctions en C que je ne peux pas vous passer par contre. C'est vraiment une vérification syntaxiques que je voudrai ^^ et je suis ouvert à toutes critiques , comme ce sont mes deux premiers scripts ils doivent être bourré de bétises.

Dernière modification par nira83 (Le 21/04/2011, à 08:49)

Hors ligne

#2 Le 20/04/2011, à 10:43

FRUiT

Re : Bash - verification de code

Deux ou trois remarques pour commencer (j'ai juste survolé le code) :

- La forme `commande` est obsolète, à remplacer par $(commande).

- let "f = f + TIME" peut s'écrire en bash f+=$TIME (en sh, peut s'écrire f=$(($f+$TIME)) )

- Pour les chaines de caractères, dans tes tests tu entoures le motif avec des guillemets, mais pas la variable ce qui n'est pas très cohérent. exemple elif [ $MODE = "AVERAGE" ] devrait être elif [ "$MODE" = "AVERAGE" ].

- Pour les valeurs de type numérique, lors des tests on utilise pas le = (qui ne sert qu'aux chaines) mais plutôt les opérateurs -eq, -ne, -gt, -lt, -ge, -le. exemple if [ $commande -eq 0 ].

- Pour les tests, et si tu restes en bash, préfère le récent test [[ plutôt que [. Exemple : elif [[ "$MODE" = "AVERAGE" ]]. Ces nouveaux tests sont mieux, bien qu'ici tu n'en exploites pas les nouvelles possibilités. Il vaut mieux s'entrainer à toujours les utiliser.

- Pourquoi utiliser du bash alors que sh serait amplement suffisant pour un script de ce genre ? C'est un peu comme si tu louais TIANHE-1a pour effectuer "2+2".

- On peut raccourcir quelques parties du genre :

if [ $commande = 0 ]
        then
            commande="NORMAL"
        else
            echo "N or R, not NR"
            exit
        fi    

Peut s'écrire (aussi bien bash que sh) :

[ $commande -eq 0 ] && commande="NORMAL" || { echo "N or R, not NR" ; exit ; }

Dernière modification par FRUiT (Le 20/04/2011, à 11:00)


Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#3 Le 20/04/2011, à 12:30

nira83

Re : Bash - verification de code

Merci pour tes réponses , je vais arranger ça big_smile
Mais maintenant je me pose quelques questions :

- La forme `commande` est obsolète, à remplacer par $(commande).

$commande est équivalent à $(commande) ?

- Pour les chaines de caractères, dans tes tests tu entoures le motif avec des guillemets, mais pas la variable ce qui n'est pas très cohérent. exemple elif [ $MODE = "AVERAGE" ] devrait être elif [ "$MODE" = "AVERAGE" ].

Je n'y ai même pas songer. Il n'y aucune différence dans l'exécution du scripte?

- Pour les valeurs de type numérique, lors des tests on utilise pas le = (qui ne sert qu'aux chaines) mais plutôt les opérateurs -eq, -ne, -gt, -lt, -ge, -le. exemple if [ $commande -eq 0 ].

Alors voila un truc qui m'a rendu fou , moi qui vient du monde du C. Bash( enfin les scripts en générales) prend tout comme des caractères!
Si je pars dans l'optique que 0 est un caractère alors je dois écrire :

if [ "$commande" = "0" ]
then
...
fi

Si je pars dans l'optique que 0 est un chiffre alors je dois écrire :

if [ $commande -eq 0 ] #sans les guillemets autour de $commande ? >> "$commande" ?
then
...
fi

C'est bien ça?
Au niveau de mon programme c'est des oublis. Et je n'y suis jamais revenu dessus voyant que ça marchait comme ça ^^.


- Pour les tests, et si tu restes en bash, préfère le récent test [[ plutôt que [. Exemple : elif [[ "$MODE" = "AVERAGE" ]]. Ces nouveaux tests sont mieux, bien qu'ici tu n'en exploites pas les nouvelles possibilités. Il vaut mieux s'entrainer à toujours les utiliser.

Qu'apportent ils de plus par rapport aux anciens?

- Pourquoi utiliser du bash alors que sh serait amplement suffisant pour un script de ce genre ? C'est un peu comme si tu louais TIANHE-1a pour effectuer "2+2".

Disons que je connaissais l'existence du bash, mais je n'en avais jamais fais. J'ai découvert ce langage il y a 15 jours . Mon tuteur m'a parlé de bash alors j'ai foncé. neutral Même si ça fait quelques années que je travail sous linux , je ne mettais jamais intéressé plus que ça aux possibilités du shell et des scripts.
Mais bon TIANHE-1a fera très bien l'affaire pour réaliser 2+2 tongue

en tous cas merci pour tes réponses , je corrigerais ça big_smile
Quelques lignes de gagnées c'est cool big_smile

Hors ligne

#4 Le 20/04/2011, à 13:17

twocats

Re : Bash - verification de code

    x)    mtu=$OPTARG
    esac

Dans le deuxième script il manque un ';;' :

    x)    mtu=$OPTARG
              ;;
    esac

La réponse est 42

Hors ligne

#5 Le 20/04/2011, à 14:37

FRUiT

Re : Bash - verification de code

nira83 a écrit :

Merci pour tes réponses , je vais arranger ça big_smile
Mais maintenant je me pose quelques questions :

- La forme `commande` est obsolète, à remplacer par $(commande).

$commande est équivalent à $(commande) ?

Non, $commande, ou plus généralement $var fait référence à la valeur de la variable var.
$(commande) substitue le résultat de la ligne de commande commande.
Exemple :

> var="date"
> echo $var
date
> var="`date`"
> echo $var
mercredi 20 avril 2011, 15:01:48 (UTC+0200)
> var="$(date)"
> echo $var
mercredi 20 avril 2011, 15:01:48 (UTC+0200)
>

Les backquotes « ` » sont l'ancienne forme de la substitution. Par exemple, elles supportent très mal l'imbrication, alors que la forme $( ), elle, la supporte sans limite.

nira83 a écrit :

- Pour les chaines de caractères, dans tes tests tu entoures le motif avec des guillemets, mais pas la variable ce qui n'est pas très cohérent. exemple elif [ $MODE = "AVERAGE" ] devrait être elif [ "$MODE" = "AVERAGE" ].

Je n'y ai même pas songer. Il n'y aucune différence dans l'exécution du scripte?

Le test pourrait éventuellement échouer si la valeur de MODE contient des espaces (à moins d'utiliser le test [[). Et puis en toute logique, tu protèges une partie du test alors pourquoi pas l'autre. Si MODE ne contient jamais d'espaces, pas de différence non.

nira83 a écrit :

- Pour les valeurs de type numérique, lors des tests on utilise pas le = (qui ne sert qu'aux chaines) mais plutôt les opérateurs -eq, -ne, -gt, -lt, -ge, -le. exemple if [ $commande -eq 0 ].

Alors voila un truc qui m'a rendu fou , moi qui vient du monde du C. Bash( enfin les scripts en générales) prend tout comme des caractères!
Si je pars dans l'optique que 0 est un caractère alors je dois écrire :

if [ "$commande" = "0" ]
then
...
fi

Si je pars dans l'optique que 0 est un chiffre alors je dois écrire :

if [ $commande -eq 0 ] #sans les guillemets autour de $commande ? >> "$commande" ?
then
...
fi

C'est bien ça?

Tout à fait c'est bien ça. J'ai pas trop d'exemple précis sous la main là, mais comparer des nombres en tant que chaines de caractères peut occasionner des problèmes. Etant donné qu'un nombre ne contient en tout logique aucun espace, il ne faut pas les protéger avec des guillemets, ou alors ils seront considérés comme une chaine de caractère. Cela vient principalement du fait que en bash (et en shell en général) les variables ne sont pas typées (elles commencent à l'être depuis bash avec l'instruction declare). En fait la syntaxe utilisée pour le test va implicitement indiquer à bash comment comparer les expressions (ou variables), et de quel type les considérer. Dans ton cas (expressions très très simples) la comparaison en tant que chaine marche également.

nira83 a écrit :

- Pour les tests, et si tu restes en bash, préfère le récent test [[ plutôt que [. Exemple : elif [[ "$MODE" = "AVERAGE" ]]. Ces nouveaux tests sont mieux, bien qu'ici tu n'en exploites pas les nouvelles possibilités. Il vaut mieux s'entrainer à toujours les utiliser.

Qu'apportent ils de plus par rapport aux anciens?

Notamment la gestion des espaces dans les expressions comparées même sans guillemets de protection, ainsi que la comparaison "approximative" avec des REGEX (pour les améliorations que je connais, il y en a surement d'autres).

nira83 a écrit :
- Pourquoi utiliser du bash alors que sh serait amplement suffisant pour un script de ce genre ? C'est un peu comme si tu louais TIANHE-1a pour effectuer "2+2".

Disons que je connaissais l'existence du bash, mais je n'en avais jamais fais. J'ai découvert ce langage il y a 15 jours . Mon tuteur m'a parlé de bash alors j'ai foncé. neutral Même si ça fait quelques années que je travail sous linux , je ne mettais jamais intéressé plus que ça aux possibilités du shell et des scripts.
Mais bon TIANHE-1a fera très bien l'affaire pour réaliser 2+2 tongue

Libre à toi, mais sache quand même que les systèmes *nix dans leur ensemble n'ont pas tous bash, et les versions de bash diffèrent également beaucoup de l'un à l'autre. Pour sh c'est quand même un peu plus uniformisé (mais pas complètement non plus), c'est donc après une question de portabilité vers d'autres systèmes smile

Dernière modification par FRUiT (Le 20/04/2011, à 15:00)


Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#6 Le 20/04/2011, à 15:45

nira83

Re : Bash - verification de code

Merci Twocats, c'est lgenre d'erreurs qui n'empeche pas le programme de marcher sauf que tu ajoute une ligne sans faire attention!C'est corrigé.

Merci pour le détail des réponses FRUiT big_smile
C'est entrain d'être corrigé!
D'autres choses affreuses?

En tous cas merci big_smile c'est pratique une petite vérification d'un oeil externe et précis !

Hors ligne

#7 Le 20/04/2011, à 15:54

FRUiT

Re : Bash - verification de code

Plutôt que déclarer :

MODE=0

Pour ensuite vérifier sa valeur :

    a)      if [ $MODE = 0 ]
                then
                        MODE="AVERAGE"
            MAX=$OPTARG
                else
                        echo "Only s or n or a"
                        exit
                fi 


Pourquoi ne pas simplement tester l'existence de MODE, ce qui évite toute déclaration préalable :

    a)     [ -z "$MODE" ] && { MODE="AVERAGE" ; MAX=$OPTARG ; } || { echo "Only s or n or a" ; exit ; }  ;;

Ca fait quand même un sacré nombre de lignes VAR=0 en moins...

Dernière modification par FRUiT (Le 20/04/2011, à 16:10)


Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#8 Le 20/04/2011, à 16:00

AnsuzPeorth

Re : Bash - verification de code

Bjr,
Ma petite pierre à l'édifice !
Plutôt que d'utiliser la commande seq (une commande supplémentaire):
si pas besoin de séquence:

for i in {0..10}; do echo $i; done

sinon, à la mode C

for ((i=0;i<=10;i++)); do echo $i; done

C'est pour chipoter big_smile


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#9 Le 20/04/2011, à 16:12

FRUiT

Re : Bash - verification de code

Ou encore avec un pas (j'ai vu un cas) :

for ((i=0;i<=10;i+=$STEP)); do echo $i; done

Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#10 Le 20/04/2011, à 16:19

AnsuzPeorth

Re : Bash - verification de code

Les variables entre doubles parenthèses n'ont pas besoin de $

for ((i=0;i<=10;i+=STEP)); do echo $i; done

ou encore

var=$((var+1))

Je sais pas si c'est bash style, mais ça fonctionne !


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#11 Le 20/04/2011, à 17:08

FRUiT

Re : Bash - verification de code

Fectivement ^^

Cette forme :

var=$((var+1))

Est un bashisme, ça ne fonctionne pas en sh. Le for style C non plus du reste.

Dernière modification par FRUiT (Le 20/04/2011, à 17:09)


Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#12 Le 21/04/2011, à 08:07

nira83

Re : Bash - verification de code

Bonjour !
Avant que j'effectue la modification, pour le cas :

for i in `seq $MIN $STEP $MAX`;
do
...
done

Je peux donc écrire de cette façon?

for ((i=MIN;i<=MAX;i+=STEP));
do 
...
done

autre question :

while getopts NRsna:A:u:w:m:M:S:r:P:I:x: option
do
    case $option in
    N)     [ -z "$commande" ] && { commande="NORMAL" ; } || { echo "N or R, not NR" ; exit ; }  ;;
    R)     [ -z "$commande" ] && { commande="RAW" ; } || { echo "R or N not RN" ; exit ; }  ;;
    s)     [ -z "$MODE" ] && { MODE="SIZE" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    n)     [ -z "$MODE" ] && { MODE="NUMBER" ; } || { echo "Only s or n or a" ; exit ; }  ;;
    a)     [ -z "$MODE" ] && { MODE="AVERAGE" ; MAX=$OPTARG ; } || { echo "Only s or n or a" ; exit ; }  ;;
    A)    TIME=$OPTARG     ;;
    m)    MIN=$OPTARG     ;;
    M)    MAX=$OPTARG     ;;
    S)    STEP=$OPTARG     ;;
    r)    FILE=$OPTARG     ;;
    I)    network=$OPTARG    ;;
    P)    ad_dst=$OPTARG    ;;
    u)    MIN=$OPTARG     ;;
    w)    STEP=$OPTARG    ;;
    x)    X=$OPTARG    ;;
    esac
done

J'ai modifié le code de cette façon , est ce correcte?
________________
Peut on réduire ce code , de la façon à avoir sur une seul ligne les conditions , et ce qui en découle?
Comme il est construit avec des enchaines de if ...elif ...elif ...

if [ -z "$MIN" ] && [ -z "$MAX" ] && [ -z "$STEP" ]
    then
        MIN=100
        MAX=1000  
        STEP=10
    elif [ -z "$MIN" ] && [ -z "$MAX" ] && [ -n "$STEP"  ]
    then
        MIN=$STEP
        let "MAX = 100 * STEP"
    elif [ -z "$MIN" ] && [ -z "$STEP" ] && [ -n "$MAX" ]
    then
        let "STEP = MAX / 100"
        let "MIN = STEP"
    elif [ -z "$MIN" ] && [ -n "$STEP" ] && [ -n "$MAX" ]
    then
        let "MIN = STEP"
    elif [ -z "$MAX" ] && [ -n "$STEP" ] && [ -n "$MIN" ]
    then
        let "MAX = 100 * STEP"
    elif [ -z "$MAX" ] && [ -z "$STEP"  ] && [ -n "$MIN"  ] 
    then
        STEP=$MIN
        let "MAX = 100 * STEP"
    elif [ -z "$STEP" ] && [ -n "$MIN" ] && [ -n "$MAX" ]
    then
        STEP=10
    fi

Merci encore pour vos réponses Petit à petit le code prend de la classe ^^

Edit :
J'ai modifié le premier post en y incluant quelques modifications que vous m'aviez signalées.

Dernière modification par nira83 (Le 21/04/2011, à 08:50)

Hors ligne