[SHELL/UNIX] boucle

boucle [SHELL/UNIX] - Shell/Batch - Programmation

Marsh Posté le 11-04-2010 à 11:06:10    

Bonjour et bon dimanche à tous,
 
N'étant point programmeur et coincant depuis quelques temps sur un "simple" programme visiblement. Avant d'être la risée de mes collègues ^^, je vous expose ci dessous le script qui ne marche pas :  
 
#!/bin/ksh
# Test script pour archive Logs XXXX
# Variables
ARCHIVE_LOG=/home/toto/Archives
REP_LOG=/home/toto
 
echo ------------------------------------------------------------------
echo               Test script
echo -----------------------------------------------------------------
 
 
# Verification de la presence du batch
# Si process absent, on peut archiver
 
for i in `cat /home/toto/liste_batch.txt`
do
ps auxw | grep $i | grep -v grep | wc -l >> /home/toto/found.txt
done                      
found=/home/toto/found.txt
if [  grep $found = 1 ]
then
echo " Job en cours - Attendre" >> /home/toto/test-script.log 2>&1
else
mv $REP_LOG/BATCH1* $ARCHIVE_LOG/  >> /home/toto/test-script.log 2>&1
echo " Job termine - Pret a etre archive " >> /home/toto/test-script.log 2>&1                                    
fi
>/home/toto/found.txt
 
 
----> j'ai l'erreur suivante   "  test-script.ksh[24]: [: /home/toto/found.txt: unknown operator
 
C'est vrai je ne suis pas doué en programmé, il y a surement plus simple en plus.
 
Ce que je veux faire : il y a des process qui tournent (batch) et je veux que si un process est tjrs en cours, alors ne pas archiver sa log, sinon j'archive. script que l'on me demande d'automatiser sur 15 machines à mettre dans la crontab.
 
Merci à tous de vos conseils...  

Reply

Marsh Posté le 11-04-2010 à 11:06:10   

Reply

Marsh Posté le 11-04-2010 à 21:31:13    

Ton script croit que tu veux faire une division /home/toto/found.txt , parfois il faut protéger les opérateurs.
Il y a plusieurs possibilités, soit en fixant toute l'expression entre apostrophes, soit en mettant un anti_slash devant chaque opérateur à protéger.

 

Essaie found='/home/toto/found.txt'

 


PS: je n'ai pas lu la suite, mais je crois que ça risque de bloquer sur d'autres trucs.


Message édité par tuxerman12 le 11-04-2010 à 21:36:55
Reply

Marsh Posté le 13-04-2010 à 12:34:09    

Bon alors euh..... on va faire un premier tour d'horizon, avec quelques explications histoire que ça reste ^^ (si je me plante, merci aux lecteurs de me corriger ! :jap: )
 
1 - Les variables avec du texte dedans
tuxerman12 a totalement raison : plus tu es précis avec Unix, moins tu as de chances qu'il n'essaye d'interpréter ce que tu lui dis.
 
Donc première règle à suivre : tout ce qui est chaînes de caractères (en gros tout texte que tu veux mettre dans une variable) devrait être encadré d'apostrophes. Et là encore y a une finesse : si tu utilises les doubles quotes ( " ) alors le KSH peut interpréter d'éventuelles variables à l'intérieur de ta chaîne de caractères. Si tu utilises la simple quote ( ' ) alors la chaîne est conservée telle quelle.
Exemple :  

Code :
  1. t01k2 @ </tst01/K2>
  2. > echo "$USER"
  3. t01k2
  4. t01k2 @ </tst01/K2>
  5. > echo '$USER'
  6. $USER


 
2 - Utilisation des variables
Tu peux également encadrer tes noms de variables afin de ne laisser aucune chance au shell de t'embrouiller. Par exemple (attention exemple tordu, mais c'est juste pour illustrer :pt1cable: ), je définis une variable USE='Bonjou' et je fais la commande suivante :
echo $USER
Comment qu'il fait pour savoir si c'est $USE  + R ou $USER ? ==> encadrer les variables avec des accolades ( ${...} ) ==> echo ${USE}R
 
3 - La commande de test magique
Cette commande là, elle est pas belle :

Code :
  1. if [  grep $found = 1 ]


Je comprend ce que tu veux faire, mais à moins que certaines subtilités du shell ne m'échappent, je ne pense pas que cette commande passe et te renvois ce que tu veux ....
Personnellement  je passerai par une variable 'found' plutôt que par un fichier, plus pratique et ça ne pollue pas ton disque un fois que le script est terminé.
 
Donc déjà on peut essayer avec les modifications suivantes :

Code :
  1. #!/bin/ksh
  2. # Test script pour archive Logs XXXX
  3. # Variables
  4. ARCHIVE_LOG="/home/toto/Archives"
  5. REP_LOG="/home/toto"
  6. echo ------------------------------------------------------------------
  7. echo               Test script
  8. echo -----------------------------------------------------------------
  9. # Verification de la presence du batch
  10. # Si process absent, on peut archiver
  11. found=0
  12. for i in `cat /home/toto/liste_batch.txt`
  13. do
  14. found=$((${found} + `ps auxw | grep $i | grep -v grep | wc -l`))
  15. done                     
  16. if [ ${found} -ne 0 ]
  17. then
  18. echo " Job en cours - Attendre" >> /home/toto/test-script.log 2>&1
  19. else
  20. mv ${REP_LOG}/BATCH1* ${ARCHIVE_LOG}/  >> /home/toto/test-script.log 2>&1
  21. echo " Job termine - Pret a etre archive " >> /home/toto/test-script.log 2>&1                                   
  22. fi


 
Remarque : le script en l'état tel que tu nous l'as décrit au départ va chercher n'importe quel process de la liste : dès qu'il en trouve un il ne fera pas l'archive !
Ce qui n'est pas la même chose que : je regarde si tel process est ectif, si oui j'archive SON log, sinon je passe au suivant .........
 
Voilà voilà


Message édité par Kerrozen le 13-04-2010 à 12:37:25

---------------
En programmation, quand t'as un problème et qu'il n'y a que deux solutions valides, seule la troisième fonctionne !
Reply

Marsh Posté le 13-04-2010 à 13:14:45    

ou

 
Code :
  1. FOUND=0
  2. for i...
  3. do
  4.   ps | grep -v grep | grep $i
  5.   if [ $? = 0 ] ; then
  6.     FOUND=1
  7.     break
  8.   fi
  9. done
  10. if [ $FOUND...] ; then
  11.   ...
  12. fi
 

$? donne le résultat de la dernière commande (c'est pour ça que j'ai d'abord mis le grep -v).

 

pour grep (cfr. man),

Citation :

$? = 0 s'il trouve au moins un "match"
$? = 1 sinon

 

$? = 2 en cas d'erreur


Message édité par art_dupond le 13-04-2010 à 13:18:30

---------------
oui oui
Reply

Marsh Posté le 13-04-2010 à 16:12:52    

Effectivement la solution d'Art_dupond te permet de gagner du temps : tu sors dès que tu trouves un process qui est dans ta liste.
 
En cherchant bien y a certainement plusieurs moyens d'optimiser ton truc mais sur le coup j'ai eu la flemme ^^
 
Confirme-nous déjà que ça fonctionne, et surtout que c'est bien ce que tu veux faire (ne pas faire le 'mv' vers le dossier d'archive dès qu'un process de la liste est trouvé)


---------------
En programmation, quand t'as un problème et qu'il n'y a que deux solutions valides, seule la troisième fonctionne !
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed