Forum Programmation.autre [bash] bug dans mon script

Posté par  (site web personnel) .
Étiquettes : aucune
-2
2
mai
2009

Bonjour, j'ai un bug dans mon script bash que je ne sais pas résoudre, voila mon script:
#!/bin/bash

DATE=`date`
URL=""
ADMIN=""
URLCHECK=""

echo "Check internet connexion..."
/usr/bin/lynx -verbose -connect_timeout 10 -source ${URLCHECK} > /dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Internet connexion ok"
if [ -f "/root/state/connection" ] ; then
echo " Connexion internet up"

# mail here for new state ok
/usr/sbin/sendmail -oi $ADMIN << EOF
Subject: Connexion internet up
From: check-script <$ADMIN>
To: BRULE Herman <$ADMIN>

Connexion internet is up since $DATE

EOF

rm -f "/root/state/connection"
fi
echo "Start list..."
LISTTEMP=`/usr/bin/lynx -source ${URL}list_http.php`
if [ $? -eq 0 ] ; then
echo "Start scanning..."
for a in $LISTTEMP
do
echo "$a checking ..."
FILE="/root/state/`echo $a | md5sum` Mailed"
CHECKSTATE=0
CONTENT=`/usr/bin/lynx -connect_timeout 5 -source $a`
RETURNVAL=$?
if [ `echo $a | grep return-state.php | wc -l` -eq 1 ] ; then

if [ $RETURNVAL -eq 0 ] && [ $CONTENT = "ok" ] ; then
CHECKSTATE=1
fi
else
CONTENT=`/usr/bin/lynx -connect_timeout 5 -source $a`
if [ $RETURNVAL -eq 0 ] && [ `echo $CONTENT | grep "Can't connect to"` = "" ] && [ $CONTENT != "" ] ; then
CHECKSTATE=1
fi
fi
if [ $CHECKSTATE -eq 1 ] ; then
echo "$a is ok"
if [ -f "$FILE" ] ; then
rm -f "$FILE"

# mail here for new state ok
/usr/sbin/sendmail -oi `/usr/bin/lynx -source ${URL}get_mail.php?url=$a` << EOF
Subject: Web site up
From: check-script <$ADMIN>
To: `/usr/bin/lynx -source ${URL}get_name.php?url=$a` <`/usr/bin/lynx -source ${URL}get_mail.php?url=$a`>

The web site $a is up since $DATE

EOF

echo "$DATE: Web site have ok"
fi
else
echo "$a is failed"
if [ -f "$FILE" ] ; then
echo "" > /dev/null 2>&1
else
date >> "$FILE"
if (( $RETURNVAL != 0 )); then
echo "RETURNVAL = $RETURNVAL" >> "$FILE"
fi
if [ $CONTENT = "" ]; then
echo "CONTENT is empty" >> "$FILE"
fi
if [ `echo $CONTENT | grep "Can't connect to"` != "" ]; then
echo "CONTENT have \"Can't connect to\":" >> "$FILE"
echo -ne "$CONTENT" >> "$FILE"
fi

# mail here for new state failed
/usr/sbin/sendmail -oi `/usr/bin/lynx -source ${URL}get_mail.php?url=$a` << EOF
Subject: Web site down
From: check-script <$ADMIN>
To: `/usr/bin/lynx -source ${URL}get_name.php?url=$a` <`/usr/bin/lynx -source ${URL}get_mail.php?url=$a`>

The web site $a is down since $DATE

EOF

echo "$DATE: Web site have failed"
fi
fi
done
fi
else
echo "Internet connexion failed"
if [ -f "/root/state/connection" ] ; then
echo "" > /dev/null 2>&1
else
date > "/root/state/connection"
echo "Connexion internet down"

# mail here for new state ok
/usr/sbin/sendmail -oi $ADMIN << EOF
Subject: Connexion internet down
From: check-script <$ADMIN>
To: BRULE Herman <$ADMIN>

Connexion internet is down since $DATE

EOF

fi
fi

Et voila l'erreur:
/root/script/check-external.sh: line 44: [: =: unary operator expected

/root/script/check-external.sh: line 74: [: too many arguments
/root/script/check-external.sh: line 77: [: !=: unary operator expected

Quelqu'un pourrai me donner un coup de main? Merci d'avance.
  • # o/*

    Posté par  . Évalué à 2.

    Désolé de pas mettre la solution direct sur le site, mais j'ai passé plus de temps à essayé d'avoir un affichage correct plutot qu'a débugger ton truc :s

    Du coup http://pastebin.com/m35421a2e


    En gros, t'avais des = au lieu de == et des grep que j'ai changer par des grep -c. (man grep pour les détails).
    A priori, ça marche.
    • [^] # Re: o/*

      Posté par  . Évalué à 2.

      En gros, t'avais des = au lieu de ==

      On est en Bash. À l'intérieur de l'opérateur de test, ça reste une comparaison.
  • # Développement avant évaluation

    Posté par  . Évalué à 5.

    Le Shell est un langage symbolique. Toutes tes expressions sont d'abord développées avant d'être évaluées. C'est classique. En l'occurence, à la ligne :

    if [ $RETURNVAL -eq 0 ] && [ `echo $CONTENT | grep "Can't connect to"` = "" ] && [ $CONTENT != "" ] ; then

    Si `echo $CONTENT | grep "Can't connect to"` ne renvoie rien, tu te retrouves avec l'expression [ = "" ] dans laquelle il te manque un argument à gauche. Même chose pour

    if [ $CONTENT = "" ]; then

    mais dans l'autre sens : $CONTENT est développée en plusieurs mots là où la comparaison en attend exactement un de chaque côté. Dans certains cas, les guillemets eux-mêmes sont prédéveloppés, ce qui transforme les chaînes vides en néant. Pour pallier cela, on rajoutait un caractère identique de chaque côté.

    Dans tous les cas, les chaînes vides en Shell, c'est pas glop. Tu as l'option « -z » dans les tests pour savoir si la longueur d'une chaîne est nulle, mais surtout grep te renvoie un code d'erreur quand il n'a pas trouvé le motif que tu cherches. Donc soit tu renvoies ce qu'il sort vers /dev/null, soit tu utilises directement l'option -q, pour le faire taire, et tu exploites directement ce qu'il te dit avec des pseudos ET ou OU.

    echo "Foobar" | grep Foobar > /dev/null && echo "Trouvé"

    Ça t'évite d'avoir à lancer un sous-Shell.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.