Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1215 connectés 

  FORUM HardWare.fr
  Programmation
  Shell/Batch

  [SHELL/UNIX] boucle

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[SHELL/UNIX] boucle

n°1982907
moicava75
Posté le 11-04-2010 à 11:06:10  profilanswer
 

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...  

mood
Publicité
Posté le 11-04-2010 à 11:06:10  profilanswer
 

n°1983027
Tuxerman12
Posté le 11-04-2010 à 21:31:13  profilanswer
 

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
n°1983551
Kerrozen
To be or not to be ... cool ..
Posté le 13-04-2010 à 12:34:09  profilanswer
 

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 !
n°1983572
art_dupond
je suis neuneu... oui oui !!
Posté le 13-04-2010 à 13:14:45  profilanswer
 

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
n°1983670
Kerrozen
To be or not to be ... cool ..
Posté le 13-04-2010 à 16:12:52  profilanswer
 

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 !

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Shell/Batch

  [SHELL/UNIX] boucle

 

Sujets relatifs
problème dans une boucle (masquer les lignes vides)Substitution dans une boucle for
Action executé periodiquement dans une boucleexecuter un script shell dans une page web
Condition non null pour rentrer dasn ma boucleArgument -- dans un shell UNIX
[Résolu] referencer des instances creees par une fonction...Lancer un script shell (ksh) si une requete retourne une valeur
[SHELL] Renommer les noms de fichiers avec espaces 
Plus de sujets relatifs à : [SHELL/UNIX] boucle


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR