4 votes

Y a-t-il un moyen de savoir si la copie d'un fichier est terminée ?

Le scénario est le suivant : La machine A a des fichiers que je veux copier sur la machine C. La machine A ne peut pas accéder directement à C, mais peut accéder à la machine B qui peut accéder à la machine C. J'utilise scp pour copier de la machine A à B, puis de B à C.

La machine B dispose d'un espace de stockage limité, si bien qu'au fur et à mesure que les fichiers arrivent, je dois les copier sur C et les supprimer de B. La deuxième copie est beaucoup plus rapide, si bien que cela ne pose pas de problème de bande passante.

Je pourrais le faire à la main, mais je suis paresseux. Ce que je voudrais, c'est exécuter un script sur B ou C qui copiera chaque fichier vers C comme chacun finit . Le travail scp est exécuté à partir de A.

J'ai donc besoin d'un moyen de demander (de préférence à partir d'un script bash) si le fichier X.avi a "fini" de copier. Chacun de ces fichiers a une taille différente, et je ne peux pas vraiment prédire la taille ou le temps d'achèvement.

Edit : au fait, les temps de transfert des fichiers sont d'environ 1 heure de A à B et d'environ 10 minutes de B à C, si l'échelle de temps a une quelconque importance.

8voto

Jesse Dearing Points 1602

Une méthode courante consiste à le copier d'abord dans un nom de fichier temporaire, de préférence un fichier caché. Lorsque la copie est terminée, le script qui effectue la copie le renomme en nom de fichier non caché.

Le script sur la machine B pourrait alors surveiller les fichiers non cachés.

Le script sur la machine A ressemblerait à ceci :

for file in `ls *` ; do
    scp $file user@host:~/.${file}.tmp
    ssh user@host "mv ~/.${file}.tmp $file"
done

Bien que cela ne satisfasse pas le désir de l'OP d'utiliser la ligne unique

scp * user@host:~/

il accomplit la même chose et permet également à la machine B de transférer chaque fichier au fur et à mesure qu'il se termine, sans attendre le fichier suivant.

2voto

Metaphox Points 139

Fait lsof sur la machine B montre que scp a ouvert le fichier ? si c'est le cas, vous pouvez regarder lsof et voir quand scp ferme le fichier. Si ce n'est pas le cas, vous pouvez surveiller la taille du fichier et, lorsqu'elle n'a pas changé pendant une période donnée (5 minutes, par exemple), la copier de B vers C.

Une troisième option consisterait à copier les fichiers de A vers un répertoire "in_progress" sur C. Une fois la copie terminée sur A, exécutez une commande mv pour quitter le répertoire "in_progress".

2voto

Metaphox Points 139

Je viens de penser à une autre option, qui n'a rien à voir. Elle n'utilise pas du tout scp. N'hésitez pas à me faire savoir si cela fonctionnerait :

  1. sur B, créez un tube fifo quelque part : mkfifo /tmp/xfer

  2. sur A, n'utilisez pas scp, à la place, tar -cz files | ssh B 'cat > /tmp/xfer

  3. sur C, exécutez ssh B 'cat /tmp/xfer' | tar -xz

De cette manière, les données ne sont pas stockées sur B, elles ne font que transiter par le tuyau. L'inconvénient est que l'on ne peut avoir qu'une seule copie à la fois...

Vous devrez vous assurer que le processus sur C reprend à chaque fois qu'il se termine.

2voto

Uberfuzzy Points 2492

Après avoir réfléchi aux réponses postées (en particulier l'idée de @Josh de regarder les temps de modification), j'ai essayé de manipuler les fichiers de B sur C. En effet, B est anémique en ce qui concerne les outils disponibles, donc rien de ce qui semblait pouvoir faire le travail n'était là. J'ai trouvé cette solution. Cette idée n'est pas la mienne, je l'ai trouvée dans des recherches Google avant cette question. Je l'ai écartée plus tôt, car la machine B n'avait pas les outils nécessaires. find de l'utilitaire.

Tout d'abord, montez le répertoire approprié de B sur C, de manière à ce qu'il apparaisse comme un système de fichiers local. J'ai utilisé sshfs pour cela (outil génial, soit dit en passant). Cela me permettra d'utiliser les utilitaires de C au lieu de ceux de B.

Deuxièmement, le commandement find /the/folder/* -mmin +5 correspondra à tous les fichiers modifiés il y a plus de 5 minutes. Ainsi, la commande find /the/folder/* -mmin +5 -exec {} /the/other/folder \; déplacera tous les fichiers qui ont été modifiés il y a plus de 5 minutes dans l'autre dossier (qui est en fait sur C, au lieu de sshfs monté à partir de B.

Enfin, j'ai créé un cron script pour exécuter le script ci-dessus toutes les 10 minutes aujourd'hui et demain. La ligne dans ma crontab ressemble à ceci.

*/5 * 22,23 9 * find /the/folder/* -mmin +5 -exec mv {} /the/other/folder \;

J'espère que cela fonctionnera. Le fichier suivant n'est pas encore terminé, je ne peux donc pas dire s'il fonctionne vraiment lorsqu'il est combiné avec le cron script, mais j'ai créé quelques fichiers à la main et je les ai ensemencés et ils se sont déplacés sans problème. croiser les doigts

Edit : Cela fonctionne, bien que la façon dont c'était à l'origine comportait quelques erreurs, qui sont maintenant corrigées.

1voto

tuomassalo Points 443

Pas besoin de mkfifo. Sur la machine B, exécutez ceci :

ssh A 'tar -cz files' | ssh C 'tar -xz'

L'option -C de tar peut s'avérer utile.

Si vous devez lancer la copie sur la machine A, faites-le :

tar -cz files' | ssh B "ssh C 'tar -xz'"

Attention toutefois aux citations correctes.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X