[KSH] Comment tester si un fichier est complet ?

Comment tester si un fichier est complet ? [KSH] - Shell/Batch - Programmation

Marsh Posté le 24-05-2012 à 11:27:38    

Bonjour,
 
J'ai créé un shell qui surveille un répertoire et exécute une action quand un fichier arrive.
Des utilisateurs peuvent déposer des gros fichiers via ftp dans ce répertoire.
 
Le problème est que lorsqu'un fichier est en cours de transfert, il apparaît déjà dans le répertoire, donc l'action s’exécute avec un fichier à moitié téléchargé.
 
Comment faire pour tester si un fichier est complet et non erroné ?
 
Par avance merci.


---------------
Trop d'argent ? comment se ruiner . com
Reply

Marsh Posté le 24-05-2012 à 11:27:38   

Reply

Marsh Posté le 24-05-2012 à 11:47:44    

Entre temps j'ai testé ça :
 
if [[ -f $FIC && -r $FIC && -s $FIC ]]
 
Est-ce suffisant pour être sur que le fichier est complet et non erroné ?


---------------
Trop d'argent ? comment se ruiner . com
Reply

Marsh Posté le 24-05-2012 à 12:07:47    

Pour ce genre de situation, habituellement on détecte la complétion d'un fichier en vérifiant qu'il n'a pas augmenté de taille entre deux intervalles de temps (1 mn ou deux par exemple).
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 24-05-2012 à 13:57:50    

En principe pour ce genre de problème, le mieux (et le plus sur a mon sens) c'est de transférer le fichier sous un nom temporaire, et une fois le transfert terminé, il suffit de renommer le fichier avec le nom définitif.
 
Avec ce mécanisme tu peux être sur que ton fichier est correct, vu que la commande pour renommer un fichier est instantané et ne modifie en rien le contenu du fichier.
 
Une autre solution serait le dépôt d'un flag indiquant que le transfert est terminé. Donc transfert du gros fichier puis d'un fichier vide portant un nom précis, et tu ne lances ton traitement que lorsque le flag est présent. Bien sur, il faut penser à supprimer le flag lorsque tu as fini ton traitement ^^
 
D'ailleurs une bonne habitude à prendre, c'est de ne pas traiter le fichier directement dans le répertoire de transfert, mais de l'envoyer dans une autre arborescence que tu maîtrises afin d'être sur qu'un autre fichier ne viendra pas écraser celui que tu es en train de traiter.
Du coup un système de gestion par suffixe du fichier est pas mal. Du genre :
 
pendant le transfert le fichier est nommé  
fichier.transfert
Une fois fini le transfert il est nommé  
fichier
pendant le traitement il est nommé
fichier.traitement
et une fois fini soit supprimé, soit historisé sous un nom type
fichier.traite.
 
Ainsi en cas de problème dans ton traitement tu peux, rien qu'en regardant le nom du fichier, savoir ou en était le traitement et éventuellement tu peux coder un rattrapage auto.

Reply

Marsh Posté le 24-05-2012 à 14:09:59    

Nukolau a écrit :

En principe pour ce genre de problème, le mieux (et le plus sur a mon sens) c'est de transférer le fichier sous un nom temporaire, et une fois le transfert terminé, il suffit de renommer le fichier avec le nom définitif.

Ça colle quand c'est toi qui fait le transfert, cette stratégie, mais je n'ai pas l'impression que ce soit le cas ici. En tout cas, j'ai connu des cas ou tu n'as pas de contrôle sur cela ( et ou la seule chose que tu sais, c'est que des images sont déposées depuis le monde entier dans un répertoire précis, par des correspondants de presse, et qu'il faut les sauvegarder ailleurs une fois le transfert achevé )
A+,


Message édité par gilou le 24-05-2012 à 14:14:03

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 24-05-2012 à 15:21:14    

En effet gilou, c'est le cas ici, plusieurs personnes peuvent venir déposer des fichiers dans un dossier de réception. Ce dossier est monté et accessible sur plusieurs machines (qualif et prod). Lorsqu'un fichier arrive, celui-ci est copié dans un autre repertoire mais pas supprimé, puisque les autres machines doivent pouvoir y accéder aussi.
 
Ce que j'ai peut c'est que la copie commence avant le téléchargement complet du fichier. Est-ce possible ou  le cp attend que le fichier soit entier ?
 


---------------
Trop d'argent ? comment se ruiner . com
Reply

Marsh Posté le 24-05-2012 à 17:31:26    

Tu n'as pas du tout la main sur ce qu'il font ? Ils envoient le fichier directement via leur client ftp préféré ? Tu n'aurais pas moyen de leur donner un .bat par exemple qui fait le transfert ftp et le mv derrière (ou la dépose d'un flag) ?

 

Sinon c'est vraiment pas évident et tu ne pourras pas palier à tous les cas. Même la solution suggérée par Gilou (cksum identique pendant x minutes) n'est pas suffisante, si on imagine par exemple que la personne a eu une déconnexion et ne reprends le transfert que 45 min plus tard... Je pensais à lsof également, mais je n'ai pas l'impression qu'on voit le fichier comme ouvert pendant un transfert ftp. De toutes façons, on aurait le même problème qu'avec le cksum.

 

EDIT : peut-être qu'avec la fonction stat() de l'OS on peux arriver à quelque chose, mais je ne connais pas bien cette fonction :(

Message cité 1 fois
Message édité par Nukolau le 24-05-2012 à 17:32:49
Reply

Marsh Posté le 24-05-2012 à 17:35:39    

Nukolau a écrit :

Tu n'as pas du tout la main sur ce qu'il font ? Ils envoient le fichier directement via leur client ftp préféré ? Tu n'aurais pas moyen de leur donner un .bat par exemple qui fait le transfert ftp et le mv derrière (ou la dépose d'un flag) ?
 
Sinon c'est vraiment pas évident et tu ne pourras pas palier à tous les cas. Même la solution suggérée par Gilou (cksum identique pendant x minutes) n'est pas suffisante, si on imagine par exemple que la personne a eu une déconnexion et ne reprends le transfert que 45 min plus tard... Je pensais à lsof également, mais je n'ai pas l'impression qu'on voit le fichier comme ouvert pendant un transfert ftp. De toutes façons, on aurait le même problème qu'avec le cksum.

Elle marche (ou marchait, car ça date de plus de 10 ans ce dont je parle) parfaitement en production pour des grand quotidiens régionaux, hein [implementation par des potes à moi]. Les correspondants sont pas en général des personnes qui reprennent un transfert après 45mn, ni même qui ont 45mn a attendre qu'une image soit ul.  
A+,


Message édité par gilou le 24-05-2012 à 17:37:25

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 25-05-2012 à 10:47:37    

find -mmin +5
 
Suffit dans 99% des cas, une coupure de transfert + reprise 45 min plus tard, ce n'est pas une situation normale.

Reply

Marsh Posté le 25-05-2012 à 14:06:23    

On est bien d'accord ça marche dans 99.9% des cas ;) C'était un simple "warning", je ne connais pas la criticité des données chargées, ni ce qu'impliquerait de charger des données non cohérentes. Flinguer la cohérence d'une base de prod parce qu’un transfert n'a pas été jusqu'au bout, même si ça n'arrive qu'une fois tous les 2 ans, c'est une fois de trop à mon sens.
 
Mais bon dans ces cas la, c'est vrai aussi qu'on utilise pas le FTP, on ira plutôt sur des solutions type CFT avec un système d'acquittement et de contrôle que le fichier n'a pas été altéré durant le transfert.

Reply

Marsh Posté le 25-05-2012 à 14:06:23   

Reply

Marsh Posté le 25-05-2012 à 23:07:05    

Pourquoi pas un checksum ?


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 26-05-2012 à 01:25:14    

Consomme trop de ressources.

Reply

Marsh Posté le 27-05-2012 à 17:00:02    

Bonjour
Ne serait-il pas possible, quand on détecte l'arrivée d'un fichier, d'aller checker les logs du serveur ftp pour détecter et attendre la fin de transfert ? Ca doit bien être inscrit dans le log que le fichier a été transféré en entier non ???

Reply

Marsh Posté le 27-05-2012 à 17:55:51    

En espérant que les trucs déposés ne le sont que par ftp, et qu'il y a pas des utilisateurs en interne qui accèdent directement au répertoire de dépôt a travers un montage de lecteur réseau... (Loi de Murphy, toussa...)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-07-2012 à 11:56:06    

Y a t-il possibilité d'avoir ton script Choon ? Il m'interesse

Reply

Marsh Posté le 14-10-2014 à 09:29:18    

ChOoN a écrit :

Entre temps j'ai testé ça :
 
if [[ -f $FIC && -r $FIC && -s $FIC ]]
 
Est-ce suffisant pour être sur que le fichier est complet et non erroné ?


 
Bonjour,
 
Ce que tu as mis en place est exactement ce que je cherche... 3 questions :
- as-tu mis ton script en démon ?
- as-tu résolu ton pb de fin d'écriture de fichier ?
- pourrais-tu me donner copie de ton travail ?
 
D'avance merci,
Dg_Dev

Reply

Sujets relatifs:

Leave a Replay

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