Gibt es eine Möglichkeit festzustellen, ob eine Datei kopiert wird?

7448
Mike Cooper

Das Szenario sieht so aus: Maschine A hat Dateien, die ich auf Maschine C kopieren möchte. Maschine A kann nicht direkt auf C zugreifen, kann aber auf Maschine B zugreifen, die auf Maschine C zugreifen kann. Ich verwende scp, um von Maschine A nach B zu kopieren, und dann von B nach C.

Maschine B verfügt über einen begrenzten Speicherplatz. Da Dateien eingehen, muss ich sie nach C kopieren und von B löschen. Die zweite Kopie ist viel schneller, daher ist dies kein Problem mit der Bandbreite.

Ich könnte das von Hand machen, aber ich bin faul. Was ich möchte, ist ein Skript auf B oder C auszuführen, die jede Datei in C kopiert als je ein beendet . Der scp-Job wird von A ausgeführt.

Was ich also brauche, ist eine Möglichkeit (vorzugsweise aus einem Bash-Skript) zu fragen, ob die Datei X.avi "fertig" ist. Jede dieser Dateien hat eine andere Größe und ich kann die Größe oder den Zeitpunkt der Fertigstellung nicht wirklich vorhersagen.

Edit: Übrigens, die Dateiübertragungszeiten betragen ungefähr 1 Stunde von A nach B und ungefähr 10 Minuten von B nach C, wenn die Zeitskala überhaupt eine Rolle spielt.

2

6 Antworten auf die Frage

4
bmb

Ein üblicher Weg, dies zu tun, besteht darin, es zuerst in einen temporären Dateinamen zu kopieren, vorzugsweise in eine versteckte Datei. Wenn die Kopie abgeschlossen ist, wird das Skript, das die Kopie erstellt, in den nicht versteckten Dateinamen umbenannt.

Das Skript auf Maschine B könnte dann nach nicht versteckten Dateien suchen.

Das Skript auf Maschine A würde ungefähr so ​​aussehen:

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

Obwohl dies nicht den Wunsch von OP erfüllt, die einzeilige zu verwenden

scp * user@host:~/ 

Dies erledigt das gleiche und erlaubt Maschine B außerdem, jede Datei nach ihrem Abschluss zu übertragen, ohne auf die nächste Datei zu warten.

Das Problem dabei ist, dass auf der Computer-AI die Funktion `scp * user @ host: ~ /` verwendet werden soll und die zu kopierenden Dateien mehr als Maschine B ausfüllen. Ich kann also keine Dateien verschieben / umbenennen, nachdem sie von A kopiert wurden. Mike Cooper vor 15 Jahren 0
Ah, wenn ich es richtig verstehe, kopierst du mehr als eine Datei auf einmal? Von dort kommt das Problem? Josh vor 15 Jahren 0
Ja, das ist das Problem. Ich kann nicht alle Dateien auf B speichern. Diese Kopie dauert jedoch so lange, dass ich sie nicht sitzen und babysitten möchte, indem ich mir die einzelnen Dateien ansehe und sie dann kopiere. Vielleicht gehe ich mit Ihrer erweiterten Version. Mike Cooper vor 15 Jahren 0
2
Josh

Zeigt lsofauf Rechner B, dass scp die Datei geöffnet hat? Wenn ja, könnten Sie beobachten lsofund sehen, wann scp die Datei schließt. Wenn dies nicht der Fall ist, können Sie die Größe der Datei beobachten. Nachdem sich die Datei für einen bestimmten Zeitraum (z. B. 5 Minuten) nicht geändert hat, kopieren Sie sie von B nach C.

Eine dritte Möglichkeit wäre, die Dateien von A in ein "in_progress" -Verzeichnis von C zu kopieren. Nachdem die Kopie auf A beendet ist, führen Sie einen mvBefehl aus, um das Verzeichnis "in_progress" zu verlassen.

Leider scheint "lsof" auf Maschine B nicht zu existieren. Was Ihre dritte Option angeht, wird dies nicht funktionieren. Wenn ich die Kopie fertig stellen lasse, bevor ich irgendetwas tue, werde ich meinen erlaubten Speicherplatz auf B (etwa 10) überwältigen. 1). Welche Lösung ich auch habe, muss während des Kopierens funktionieren. Mike Cooper vor 15 Jahren 0
Die Wartezeit von 5 Minuten ist gut (ich habe an etwas Ähnliches gedacht), aber ich bin mir nicht ganz sicher, wie es gemacht wird. Irgendwelche Ideen? Mike Cooper vor 15 Jahren 0
Ja, ich könnte ein schnelles und schmutziges Rubin-Skript für Sie schreiben - hat Maschine B Rubin? Josh vor 15 Jahren 0
Nee. Es ist nicht unter meiner Kontrolle und scheint nichts von dem zu haben, was ich versuche und zu benutzen. Ich hatte gehofft, bash könnte etwas eingebaut haben. Obwohl ich das Skript möglicherweise von meinem lokalen Computer aus ausführen kann, werde ich damit experimentieren. Mike Cooper vor 15 Jahren 0
Ich werde sehen, ob ich so etwas in bash alleine schreiben kann. Meine Rubinstärke übertrifft jedoch meine Schlagkraft. stackoverflow.com kann möglicherweise mit einem solchen Skript helfen. Josh vor 15 Jahren 0
Ich glaube, ich habe es herausgefunden, siehe meine Antwort. Mike Cooper vor 15 Jahren 0
2
Josh

Ich dachte nur an eine andere, völlig unabhängige Option. Verwendet scp überhaupt nicht. Bitte lassen Sie mich wissen, ob dies funktionieren würde:

  1. In B erstellen Sie irgendwo eine FIFO-Pipe: mkfifo / tmp / xfer

  2. auf A, nicht scp verwenden, stattdessen tar -cz files | ssh B 'cat > /tmp/xfer

  3. auf C laufen ssh B 'cat /tmp/xfer' | tar -xz

Auf diese Weise werden Daten nicht auf B gespeichert, sondern durchlaufen die Pipe. Der Nachteil ist, dass Sie immer nur eine Kopie haben können ...

Sie müssen sicherstellen, dass der Prozess in C bei jedem Abschluss erneut erscheint.

Die Art und Weise, wie Sie dies erklären, scheint zu funktionieren ... aber es scheint ein bisschen "dunkle Magie" für meinen Geschmack. Ich denke, dass eine andere Lösung gefunden wurde, die auf originelle Weise funktioniert, aber ich werde dieses Snippet auf jeden Fall für den späteren Gebrauch aufbewahren. Mike Cooper vor 15 Jahren 0
Dieser Weg ist nicht wirklich "dunkle Magie", sondern es werden nur Pipes verwendet, eine Standard-Betriebssystemeinrichtung. Aber ich mag Ihre andere Lösung besser, es ist weniger Code und wahrscheinlich einfacher zu warten. Josh vor 15 Jahren 0
Oh, ich meine nicht nur, dass es magisch ist, denn ich habe noch nie mit FIFO-Pfeifen gespielt und es ist etwas, das nicht so oft verwendet wird wie andere Dinge. Obwohl jetzt etwas zu lernen. Auch Wartung ist kein großes Problem. Dies wird für ungefähr einen Tag eingerichtet werden. Mike Cooper vor 15 Jahren 0
2
Mike Cooper

Nachdem ich über die geposteten Antworten nachgedacht hatte (insbesondere @ Joshs Idee, modifizierte Zeiten zu sehen), versuchte ich, Bs Dateien auf C zu manipulieren. Sehen Sie, B ist soweit vorhanden, was die verfügbaren Tools angeht, also nichts, was die Aufgabe erfüllen könnte war dort. Ich bin auf diese Lösung gestoßen. Diese Idee ist nicht meine, ich habe sie vor dieser Frage in Google-Suchen gefunden. Ich habe es früher verworfen, da Maschine B das findDienstprogramm nicht hatte.

Hängen Sie zuerst das entsprechende Verzeichnis in B in C an, sodass es als lokales Dateisystem angezeigt wird. Ich habe sshfsdafür (tolles Werkzeug, übrigens) verwendet. Dadurch kann ich die Dienstprogramme von C anstelle von B verwenden.

Zweitens stimmt der Befehl find /the/folder/* -mmin +5mit allen Dateien überein, die vor mehr als 5 Minuten geändert wurden. Der Befehl find /the/folder/* -mmin +5 -exec {} /the/other/folder \;verschiebt also alle Dateien, die vor mehr als 5 Minuten geändert wurden, in den anderen Ordner (der sich eigentlich auf C befindet, anstatt von sshfs, die von B geladen werden.)

Schließlich habe ich ein cron-Skript eingerichtet, um das obige Skript heute und morgen alle 10 Minuten auszuführen. Die Linie in meiner Crontab sieht so aus.

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

Hoffentlich klappt das. Die nächste Datei ist noch nicht fertiggestellt, daher kann ich nicht kommentieren, ob sie wirklich funktioniert, wenn sie mit dem cron-Skript kombiniert wird, aber ich habe einige Dateien von Hand erstellt und sie ausgesät und sie haben sich gut bewegt. drücke die Daumen

Edit: Das funktioniert, obwohl es ursprünglich einige Fehler hatte, werden diese jetzt korrigiert.

Das klingt nach einer großartigen Lösung Josh vor 15 Jahren 0
1
tuomassalo

No need for mkfifo. On machine B, run this:

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

You might find tar's -C option useful.

If you need to initiate the copying on machine A, just do:

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

Watch out for proper quoting, though.

0
gbarry

Die Kopie wird entweder als anderer Prozess ausgeführt, oder Sie können es mit einer Subshell erzwingen. Dann können Sie ps verwenden, um den Prozess zu "beobachten" und zu sehen, wann er verschwindet.

Ich glaube auch, dass Sie in * nix die Datei löschen können, während sie kopiert wird. Das System löscht es erst, wenn das Kopierprogramm es schließt. Wenn die Kopie nicht erfolgreich ist, verlieren Sie natürlich die Datei, also nicht die beste Idee.

Ich muss nicht mehr kopieren, wenn die gesamte Kopie fertig ist, da ich viele Dateien kopiere. Ich muss wissen, wann jede einzelne Datei fertig ist. Mike Cooper vor 15 Jahren 0