Comment «cp» gère-t-il les fichiers ouverts?


15

J'ai deux répertoires distincts. L'utilisateur charge un fichier dans le premier. Il y a un cronjob en arrière-plan qui copie les fichiers toutes les 5 minutes dans le deuxième répertoire.

Que se passe-t-il si l'utilisateur n'a pas terminé son téléchargement et que le cronjob copie les fichiers? Notez que les deux répertoires appartiennent à des utilisateurs différents, le cronjob est effectué en tant que root.


veuillez lire cet article pour voir ce qui se passe dans un tel cas: unix.stackexchange.com/questions/49299/…
Serge

Merci, bon article que vous avez écrit. Mais ma question était plus liée à cp, pas à la gestion de fichiers linux en général. Je pense que peut-être cp vérifie si le fichier est toujours ouvert et attend jusqu'à ce qu'il soit fermé ou quelque chose.
Stuffy

Non. cpN'attendra pas le téléchargement complet du fichier. Comme nous nous attendons à ce que le taux de transfert réseau soit inférieur à la simple copie du fichier d'un emplacement à un autre à l'intérieur du même hôte, il cpatteindra à un moment donné la fin du fichier actuel et arrêtera la copie. La solution à votre problème peut être simple: tout d'abord, l'utilisateur télécharge le fichier avec un nom de fichier spécialement modifié (par exemple précédé de .(caractère point). Lorsque le transfert est terminé, l'utilisateur le renomme avec le nom d'origine. Ensuite, le travail cron ne regarde que pour les fichiers qui ne commencent pas ..
Serge

Réponses:


17

cpne connaît pas les fichiers ouverts. Donc, si le premier utilisateur télécharge un gros fichier et que cronjob (ou tout autre processus) commence à copier ce fichier, il ne copiera que ce qui a déjà été écrit. Vous pouvez penser à cela de cette façon - cpfait une copie de ce qui est actuellement sur le disque, peu importe si le fichier est complet. Sinon, vous ne pourriez pas copier les fichiers journaux par exemple.


Merci, c'est ce que je voulais savoir! Existe-t-il un moyen simple d'éviter cela? J'ai vérifié la page de manuel de cp mais n'ai rien trouvé d'utile.
Stuffy

Pour faire quoi exactement? Pour copier tous les fichiers sauf ceux ouverts? Je ne pense pas qu'il existe un moyen facile de le faire (à part écrire votre propre script qui utilise fuser+ cp. Une telle copie serait vraiment très peu fiable. Elle ne copiera aucun fichier ouvert dans l'éditeur de texte par exemple.
Krzysztof Adamski

@Stuffy, peut-être que dans votre cronjob, vous pourriez lister les fichiers ouverts lsof? Le résultat est censé être facile à traiter. Vous pouvez filtrer les fichiers ouverts (par exemple, par une instance de cp) pour l'écriture.
Wojtek Rzepala

@WojtekRzepala, je vais y jeter un œil, merci. J'écrirai peut-être un petit script qui sera exécuté par le cronjob
Stuffy

@Stuffy: Gardez à l'esprit qu'il peut ne pas être vraiment fiable s'il n'est pas exécuté par l'utilisateur root (le même problème se pose fuserbien sûr) car cet outil peut ne pas afficher tous les fichiers.
Krzysztof Adamski

7

cpne sait pas quels autres programmes peuvent avoir les fichiers ouverts. Il n'y a pas de magie cp. La conception d'Unix évite délibérément de mettre tout type de verrous sur les fichiers à moins qu'il n'y ait une raison impérieuse (ce qui signifie convaincant que le noyau en a besoin). Sur cette rubrique, voir La redirection de la sortie vers un fichier applique-t-elle un verrou sur le fichier?

De telles situations, où un fichier est produit par un producteur et, une fois terminé, consommé par un consommateur, sont courantes. La façon habituelle de gérer cela est de demander au producteur d'écrire un fichier temporaire que le consommateur ne recherchera pas, puis une fois que le producteur a terminé, déplacez le fichier dans un endroit où le consommateur le trouvera. Déplacer un fichier (sur le même système de fichiers) est une opération atomique: à un moment donné, pour le consommateur, le fichier passe de ne plus être là à être là.

Arrangez-vous donc pour que votre travail de téléchargement déplace les fichiers vers un répertoire différent une fois le téléchargement terminé. Pointez le travail cron vers ce répertoire différent.


6

Il semble que vous souhaitiez effectuer un travail de synchronisation de dir.

Parce que le option -u, --update decp

copier uniquement lorsque le fichier SOURCE est plus récent que le fichier de destination ou lorsque le fichier de destination est manquant

Vous pouvez donc ajouter un cronjob tel que cp -auv SOURCEDIR/* DESTDIR qui copiera les fichiers dont l'heure de modification a changé. Cela signifie que vous DESTDIRobtiendrez éventuellement la copie complète une fois le téléchargement terminé.

rsyncpeut faire le même travail. par exemple rsync -av SOURCEDIR/ DESTDIR.

Bien que l'option -a soit appliquée, certains attributs spécifiés (par exemple, la propriété) ne peuvent être conservés que par le super-utilisateur.

Voir man cp, man rsyncpour plus de détails.


Méfiez-vous simplement de vous fier aux entrées récentes du dossier de destination - il ne s'agit peut-être pas de fichiers complets.
dubiousjim
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.