script shell - Shell/Batch - Programmation
Marsh Posté le 04-09-2009 à 15:27:57
et tu gagnes quoi à recréer un topic?
EDIT: et même 2... topic en triple.
Marsh Posté le 04-09-2009 à 15:30:40
je me dis que je n'ai peut être pas bien formaliser mon problème et je ne sais pas comment supprimer les 2 précédents...
Marsh Posté le 05-09-2009 à 10:32:26
jedai97194 a écrit : je me dis que je n'ai peut être pas bien formaliser mon problème et je ne sais pas comment supprimer les 2 précédents... |
T'as une option pour supprimer les messages. Faut l'éditer puis t'as une case à cocher "Effacer le message" en bas
Concernant ta boucle for, tu pourrais rajouter un "echo $file" histoire de voir ce qui se passe. Parce que tu dis qu'elle ne s'exécute pas mais t'en as pas la preuve (et si $file n'est pas vide, elle s'exécutera !!!)
Maintenant les défauts de ton code
1) for file in `cat machin`
C'est évidemment la commande qu'on trouve dès le départ dès qu'on comprend l'utilité des backquottes. Mais le problème, c'est que le for découpe ses éléments sur l'espace. Et si une ligne de "machin" contient un espace, cette ligne sera traitée en 2 itérations et aucune des deux itérations ne fonctionnera correctement
La commande préconisée mais plus difficile à trouver tout seul est => cat machin |while read ligne
Dans cette commande, le read prenant ses infos dans l'entrée standard prendra ses infos dans les lignes de machin et comme il se cale sur le "return" et non sur l'espace, mêmes les lignes avec espaces seront traitées en une fois. Et quand le fichier a été traité, read renvoie "faux" et le while s'arrête
2) cat machin |grep "info" => dommage, 2 processus là où un seul suffirait => grep "info" machin
3) ce super vi << EOF2 fait certainement un truc magnifique... mais vi est très lourd à se charger. Ptet qu'on peut le remplacer par du sed, ou du awk. Bon, j'ai pas trop regardé en détail. Apparemment il fait de la substitution sur la ligne 1 puis rajoute une ligne. Bref
Toutefois, EOF signifient généralement End Of File. Or, cette commande n'est pas un fichier mais du texte. Personnellement j'écris plutôt "vi << _EOT_" (avec des "_" pour être certain de ne pas avoir "EOT" par erreur). Et idem pour les autres commandes <<EOF
4) if [ "$?" = "0" ] => tout faux => $? est un nombre et la comparaison numérique se fait avec "-eq" => if [ $? -eq 0 ]. Ca peut paraître idiot mais comparer "05" avec "5" avec le caractère "=" donnera faux alors que ce sont des chiffres mathématiquement égaux. Autant utiliser la bonne syntaxe surtout que plus bas il y a une comparaison "$?" -ne "0" (ici aussi les guillemets sont inutiles)
5) ton vi final pour visualiser le compte-rendu => t'aurais pas pu mettre more à la place ? Ok, admettons que tu veuilles offrir un outil de manip mais si tu bosses en environnemment fenêtré, tu peux offrir kedit à la place, plus facile à utiliser que "vi". Mais au pire, si tu veux donner à l'utilisateur la possibilité d'ouvrir un fichier log, rajoute au-moins l'option "-r" pour qu'il soit ouvert en lecture seule...
C'est à peu près tout.
Marsh Posté le 07-09-2009 à 12:10:26
tout d'abord merci à toi Sve@r pour tes commentaires. Je comprends mieux certaines subtilités. J'ai essayé ce que tu m'as dit à savoir faire un echo de $FIC_TM1 mais il n'affiche rien et donc ma boucle ne s'execute pas , pas plus que le reste du script et toujours mon unexpected end of file. Est il possible que les droits soient modifiés en cours de traitement car le ls -l me dis bien qu'il est accessible en lecture pour tous. Existe t il une option rewind en shell comme en C ?
Marsh Posté le 07-09-2009 à 19:42:01
jedai97194 a écrit : ... et toujours mon unexpected end of file. |
Oups, j'ai raté ce message dans ton premier post. Pourtant c'est le plus important.
Il indique que ton script shell n'est pas logiquement terminé lorsque la fin du script est atteinte par l'interpréteur. Ca arrive quand on oublie un mot clef done, fi ou esac.
Exemple
Code :
|
pas de done => unexpected end of file => fin de fichier inattendue
Ca arrive aussi quand on ouvre un guillemet, ou une backquotte, sans le fermer
Code :
|
pas de backquotte => unexpected end of file
Et si on rajoute la backquotte, pas de guillemet au echo => même punition
Maintenant, pour aller voir dans tout ton script l'endroit où t'as fait l'erreur...
Je peux te conseiller la manip suivante
1) tu copies ton script pour pas le perdre
2) tu supprimes dans ta boucle les 3/4 du code en ne laissant que le premier bloc
3) si ça marche, tu fais un copier/coller du bloc suivant pris dans la copie de sauvegarde que tu ramènes dans le script.
etc etc. De cette façon, tu trouveras plus facilement le bloc qui contient l'erreur de syntaxe...
[edit]supprime ce point-virgule après le for que t'as mis en rouge. Le shell n'est pas du C...
jedai97194 a écrit : ...et je dois le faire marcher pour lundi au plus tard. |
Ah ben too late.
Marsh Posté le 04-09-2009 à 15:20:59
Bonjour à tous et toutes,
Je désespère car je n'arrive pas à exécuter mon script et je dois le faire marcher pour lundi au plus tard.
Je pense avoir une idée pour résoudre mon problème mais je n'arrive pas à aller au bout.
Sur une ligne de mon script vous verrez une boucle for en rouge.
Celle ci ne s'exécute jamais et donc le reste du traitement est faux.
Je tente de récupérer par ftp des fichiers via un fichier de commande dynamique.
La liste des fichiers que je récupère est correcte mais je n'arrive pas à la lire avec le for pour faire les get adéquats.
Les droits du fichier contenant la liste sont correctes , le fichier n'est pas vide. Lors de l'exécution, j'obtiens systématiquement la même erreur :
unexpected end of file.
J'ai ciblé sur cette boucle car les différents echo que j'ai placé me laissent penser que le problème se pose à ce niveau.
Merci pour votre aide. Ci-après le script :
ver="D1.000"
pgm="yutarv.sh"
echo "Programme : $pgm"
echo "Version : $ver"
echo "Debut : "`date +"%d-%m-%Y %H:%M:%S:%N"`
# si on ne vient pas de IACSHE, on prend les parametres en ligne de commande
if [ -z "$SPLGTJOB" ] ; then
FIC_LOG="$1"
rm -f $FIC_LOG
LIG_CMD="O"
else
FIC_LOG="$SPLGTJOB"
LIG_CMD="N"
fi
if [ -d "/cygdrive/c/temp" ]; then
OS=NT
TMP="c:\\temp"
else
OS=UNIX
TMP="/tmp"
fi
USR="iac"
PASWD="iaciac"
HOME="d:\\CFU\\Arvato\\$BASE"
FIC_PJB="$TMP/w$$.pjb"
FIC_DATA=""
FIC_TMP="$TMP/w$$.tmp"
FIC_TM1="$TMP/w$$.tm1"
FIC_CTL="$TMP/w$$.ctl"
FIC_FTP="$TMP/w$$.sh"
# RAZ des fichiers
rm -f $FIC_PJB $FIC_TMP $FIC_TM1 $FIC_FTP $FIC_CTL
# Initialisation des variables
TTTE="N"
TTCD="N"
TREGLT="N"
TPIT="N"
TVTI="N"
TSTF="N"
echo "# ===========================================================================" >> $FIC_LOG
echo "# Etape 1 : telechargement des fichiers depuis Arvato" >> $FIC_LOG
echo "# ===========================================================================" >> $FIC_LOG
echo "" >> $FIC_LOG
echo "Connexion au site Arvato" >> $FIC_LOG
ftp 81.XX.XX.XXX > $FIC_TMP << EOF
kvaliac
cailavk
ls AE*
ls QE*
bye
EOF
if [ "$?" = "0" ] ; then
echo "Connexion reussi" >> $FIC_LOG
else
echo "Erreur dans la connexion" >> $FIC_LOG
cat $FIC_TMP >> $FIC_LOG
exit
fi
# Pas de detail avec le ls en ftp => pas besoin awk pour retrouver fichier
# cat $FIC_TMP | grep -v "ftp>" | awk -F " " '{printf("%s\n",$9)}' > $FIC_TM1
# awk pour eliminer les blancs en fin de ligne
cat $FIC_TMP | grep -v "ftp>" | awk -F " " '{printf("%s\n",$NF)}'> $FIC_TM1
echo "Liste des fichiers disponibles sur le site Arvato :" >> $FIC_LOG
cat $FIC_TM1 | awk -F " " '{printf(" %s\n",$1)}' >> $FIC_LOG
echo "" >> $FIC_LOG
echo "Telechargements des nouveaux fichiers..." >> $FIC_LOG
rm -f $FIC_FTP
touch $FIC_FTP
chmod 777 $FIC_FTP
FIRST="O"
echo "test">> $FIC_LOG
for file in `cat $FIC_TM1`;
do
echo "testA" >> $FIC_LOG;
if [ ! -s "$HOME/archives/$file" ] ; then
# Liste des fichiers a telecharger
echo "$file" >> $FIC_CTL
echo "testB">> $FIC_LOG
# Creation du fichier de commande ftp pour le telechargement
if [ "$FIRST" = "O" ] ; then
FIRST="N"
echo "ftp kvaliac@81.XX.XXX.XX" >> $FIC_FTP
echo "lcd $HOME/a_trt" >> $FIC_FTP
echo "testC">> $FIC_LOG
fi
echo "test2">> $FIC_LOG
echo "get $file" >> $FIC_FTP
else
echo "test3">> $FIC_LOG
echo " Fichier deja traite : $file" >> $FIC_LOG
fi
done
# Fin du fichier de commande s'il existe un debut
if [ "$FIRST" = "N" ] ; then
echo "bye" >> $FIC_FTP
echo "EOF1" >> $FIC_FTP
fi
echo "test4">> $FIC_LOG
# Execution du fichier de commande
$FIC_FTP
if [ "$?" -ne "0" ] ; then
echo "ERREUR dans le telechargement des fichiers" >> $FIC_LOG
cat $FIC_TMP >> $FIC_LOG
exit 1
fi
echo "test5">> $FIC_LOG
echo "# ===========================================================================" >> $FIC_LOG
echo "# Etape 2 : Integration dans les sas" >> $FIC_LOG
echo "# ===========================================================================" >> $FIC_LOG
echo " " >> $FIC_LOG
# S'il y a des fichiers a traiter
if [ -s "$FIC_CTL" ] ; then
for file in `cat $FIC_CTL`
do
if [ ! -s "$HOME/a_trt/$file" ] ; then
echo "ERREUR : pb de telechargement de $file" >> $FIC_LOG
else
# Comptage du nombre de lignes dans le fichier moins la ligne
# de description = nombre de lignes a inserer
nblignes=`cat $HOME/a_trt/$file | wc | awk -F" " '{printf $1}'`
nblignes=`expr $nblignes - 1`
echo "test6">> $FIC_LOG
# Recuperation du nom de la table a traiter
table=`echo "$HOME/a_trt/$file" | cut -d"." -f1 | cut -d"_" -f2`
# Mise a jour de la liste des traitement d'integration a lancer
# en etape 3
case "$table" in
OETTE|OETTA|OETTD|OEATT)
TTTE="O";;
SVTCD|SVTLC|SVTCG|SVTEC|SVTFC|SVTPA)
TTCD="O";;
OCECT)
TREGLT="O";;
OCPIT)
TPIT="O";;
SKMVT|SKLMT)
TVTI="O";;
SKSTF)
TSTF="O";;
interfaces)
break;;
esac
echo "test7">> $FIC_LOG
# Mise a jour du fichier de donnees pour le mettre en conformite
# avec GTSAS
cp $HOME/a_trt/$file $FIC_TMP
vi $FIC_TMP << EOF2
YP
:1,1s/;/,/g
:1,1s/A/a/g
:1,1s/B/b/g
:1,1s/C/c/g
:1,1s/D/d/g
:1,1s/E/e/g
:1,1s/F/f/g
:1,1s/G/g/g
:1,1s/H/h/g
:1,1s/I/i/g
:1,1s/J/j/g
:1,1s/K/k/g
:1,1s/L/l/g
:1,1s/M/m/g
:1,1s/N/n/g
:1,1s/O/o/g
:1,1s/P/p/g
:1,1s/Q/q/g
:1,1s/R/r/g
:1,1s/S/s/g
:1,1s/T/t/g
:1,1s/U/u/g
:1,1s/V/v/g
:1,1s/W/w/g
:1,1s/X/x/g
:1,1s/Y/y/g
:1,1s/Z/z/g
:1
Iprocessing-instruction target=dataset.set('sql.write') datas=insert into $table (A)
:wq
EOF2
# Creation du fichier de parametres pour GTSAS
rm -f $FIC_PJB
echo "[GTSAS]" >> $FIC_PJB
echo "CHAINE1D=$FIC_TMP" >> $FIC_PJB
echo "CHAINE2D=." >> $FIC_PJB
echo "CHAINE3D=." >> $FIC_PJB
echo "CHAINE4D=0" >> $FIC_PJB
echo "CHAINE5D=1" >> $FIC_PJB
echo "CHAINE6D=;" >> $FIC_PJB
# Integration directe du fichier
rm -f $FIC_TM1
gtumnu.exe -S $SERVEUR -B $BASE -e CFU -m GTSAS -u GTI -p $FIC_PJB -f $FIC_TM1 -L
# Si le traitement a bien ete genere
if [ "$?" = "0" ] ; then
# recuperation du fichier resultat du job
ficspl=`grep "Fichier resultat" $FIC_TM1 | awk '{print $4}'`
echo "test8">> $FIC_LOG
# Recherche des donnees inserees
nbinserees=`grep -i insertion /tmp/bob.lis | grep total | awk -F"=" '{printf $3}'`
if [ "$nblignes" = "$nbinserees" ] ; then
echo "$file OK" >> $FIC_LOG
# archivage du fichier traite
mv $HOME/a_trt/$file $HOME/archives/$file
else
echo "$file ERREUR : le nombre de lignes inserees $nbinserees ne correspond pas au nombre de lignes du fichier $nblignes" >> $FIC_LOG
fi
else
echo "$file ERREUR" >> $FIC_LOG
fi
fi
done
else
echo "" >> $FIC_LOG
echo "Aucun fichier traite" >> $FIC_LOG
fi
echo "# ===========================================================================" >> $FIC_LOG
echo "# Etape 3 : Traitement des sas pour integration dans tables definitives" >> $FIC_LOG
echo "# ===========================================================================" >> $FIC_LOG
echo "" >> $FIC_LOG
# S'il n'y a pas eu d'erreur plus haut
TEST=`grep ERREUR $FIC_LOG`
if [ -z "$TEST" ] ; then
echo "test9">> $FIC_LOG
# Liste des sas a traiter
LST_SAS=""
if [ "$TTTE" = "O" ] ; then
LST_SAS="TTTE"
fi
if [ "$TTCD" = "O" ] ; then
LST_SAS=$LST_SAS" TTCD"
fi
if [ "$TREGLT" = "O" ] ; then
LST_SAS=$LST_SAS" TREGLT"
fi
if [ "$TPIT" = "O" ] ; then
LST_SAS=$LST_SAS" TPIT"
fi
if [ "$TVTI" = "O" ] ; then
LST_SAS=$LST_SAS" TVTI"
fi
if [ "$TSTF" = "O" ] ; then
LST_SAS=$LST_SAS" TSTF"
fi
# Execution des differents traitement
for trt in $LST_SAS
do
# Integration directe du fichier
rm -f $FIC_TM1
gtumnu.exe -S $SERVEUR -B $BASE -e CFU -m $trt -u GTI -f $FIC_TM1 -L
# Si le traitement a bien ete genere
if [ "$?" = "0" ] ; then
# recuperation du fichier resultat du job
ficspl=`grep "Fichier resultat" $FIC_TM1 | awk '{print $4}'`
case "$trt" in
TTTE) TEST=`grep " .chou. " $ficspl`;;
TTCD) TEST=`grep "non transf.r.es" $ficspl | awk -F":" '{printf $2}'`;;
TREGLT) TEST=`grep "critures lues" $ficspl | awk -F":" '{printf $2}'`;
TEST1=`grep "critures transf.r.es" $ficspl | awk -F":" '{printf $2}'`;
if [ "$TEST" != "$TEST1" ] ; then
TEST="KO";
fi;;
TPIT) TEST="";;
TVTI) TEST=`grep "non trait.s" $ficspl | awk -F":" '{printf $2}'`;;
TSTF) TEST=`grep "en erreur" $ficspl | awk -F":" '{printf $2}'`;;
esac
# Si une erreur detectee, recopie du compte rendu dans le compte rendu
if [ ! -z "$TEST" -a "$TEST" != "0" ] ; then
echo "$trt ERREUR" >> $FIC_LOG
cat $ficspl >> $FIC_LOG
fi
else
echo "$trt ERREUR" >> $FIC_LOG
fi
done
TEST=`grep ERREUR $FIC_LOG`
if [ -z "$TEST" ] ; then
echo "Execution avec succes"
else
echo "Erreur dans l'execution"
fi
else
echo "Erreur dans l'execution"
fi
# Si on est en ligne de commande, demande si consultation du compte rendu
if [ "$LIG_CMD" = "O" ] ; then
echo -n "visualiser le compte rendu ?"
read a
if [ "$a" = "O" -o "$a" = "o" ] ; then
vi $FIC_LOG
fi
fi
# RAZ des fichiers
rm -f $FIC_PJB $FIC_TMP $FIC_TM1 $FIC_CTL $FIC_FTP
# Fin du script
exit