Kann ich feststellen, ob das Kopieren einer Datei abgeschlossen ist?

4

Das Szenario sieht folgendermaßen aus: Maschine A verfügt über Dateien, die ich auf Maschine C kopieren möchte. Maschine A kann nicht direkt auf C zugreifen, kann jedoch auf Maschine B zugreifen, die auf Maschine C zugreifen kann dann von B nach C.

Auf Computer B ist der Speicherplatz begrenzt. Wenn Dateien eingehen, müssen sie nach C kopiert und von B gelöscht werden. 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.

Also, was ich brauche, ist eine Möglichkeit zu fragen (vorzugsweise aus einem Bash-Skript), ob das Kopieren der 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 wichtig ist.

Mike Cooper
quelle

Antworten:

7

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 fertig ist, benennt das Skript, das die Kopie erstellt, sie in den nicht ausgeblendeten Dateinamen um.

Das Skript auf Computer B könnte dann nach nicht ausgeblendeten Dateien suchen.

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

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

Dies entspricht zwar nicht dem Wunsch von OP, die Einleitung zu verwenden

scp * user@host:~/

Es führt dasselbe aus und ermöglicht es Maschine B, jede Datei zu übertragen, wenn sie fertig ist, ohne auf die nächste Datei zu warten.

bmb
quelle
Das Problem dabei ist, dass auf der Maschine AI dies tun möchte scp * user@host:~/und die zu kopierenden Dateien mehr als Maschine B füllen würden, sodass ich Dateien nicht verschieben / umbenennen kann, nachdem sie von A kopiert wurden.
Mike Cooper
Ah, wenn ich das richtig verstehe, kopierst du mehr als eine Datei gleichzeitig? Woher kommt das Problem?
Josh
Ja, das ist das Problem. Ich kann nicht alle Dateien auf B speichern, aber diese Kopie wird so lange dauern, dass ich mich nicht hinsetzen und sie babysitten möchte, indem ich darauf achte, dass alle Dateien fertig sind, und sie dann kopiere. Vielleicht gehe ich mit deiner erweiterten Version.
Mike Cooper
2

Zeigt lsofMaschine B, dass scp die Datei geöffnet hat? In diesem Fall können Sie lsofsehen, wann scp die Datei schließt. Wenn nicht, können Sie die Größe der Datei beobachten und sie, nachdem sie sich über einen bestimmten Zeitraum (z. B. 5 Minuten) nicht geändert hat, von B nach C kopieren.

Eine dritte Möglichkeit besteht darin, die Dateien von A in ein Verzeichnis "in_progress" auf C zu kopieren. Führen Sie nach Abschluss des Kopiervorgangs auf A einen mvBefehl aus, um das Verzeichnis "in_progress" zu verlassen.

Josh
quelle
Scheint lsofauf Computer B leider nicht zu existieren. Bei Ihrer dritten Option funktioniert das nicht, denn wenn ich die Kopie beenden lasse, bevor ich etwas tue, werde ich meinen zulässigen Speicherplatz auf B (etwa 10: 1) erheblich überfordern. Welche Lösung ich auch habe, muss während des Kopierens funktionieren.
Mike Cooper
Die Idee, 5 Minuten zu warten, ist gut (ich habe mir etwas Ähnliches überlegt), aber ich bin mir nicht ganz sicher, wie es gemacht wird. Irgendwelche Ideen?
Mike Cooper
Ja, ich könnte ein schnelles und schmutziges Rubinskript für Sie schreiben - hat Maschine B Rubin?
Josh
Nee. Es steht nicht unter meiner Kontrolle und scheint keines der Dinge zu haben, die ich versuche und benutze. Ich hatte gehofft, Bash könnte etwas eingebaut haben, um dies zu tun. Obwohl ich das Skript möglicherweise von meinem lokalen Computer ausführen kann ... werde ich damit experimentieren.
Mike Cooper
Ich werde sehen, ob ich so etwas allein in bash codieren kann. Mein Rubin-Können übertrifft jedoch mein Bash-Können. stackoverflow.com kann Ihnen möglicherweise bei einem solchen Skript behilflich sein.
Josh
2

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. Erstellen Sie auf B 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 in B gespeichert, sondern nur durch die Pipe geleitet. Der Nachteil dabei ist, dass Sie immer nur eine Kopie gleichzeitig haben können ...

Sie müssen sicherstellen, dass der Prozess auf C bei jedem Abschluss neu gestartet wird.

Josh
quelle
So wie du das erklärst, scheint es zu funktionieren ... aber es scheint ein bisschen "dunkle Magie" für meinen Geschmack zu sein. Ich denke, ich habe eine andere Lösung gefunden, die auf die ursprüngliche Weise funktioniert, aber ich werde dieses Snippet definitiv für die spätere Verwendung aufbewahren.
Mike Cooper
Auf diese Weise ist nicht wirklich "dunkle Magie", sondern es werden nur Pipes verwendet, was eine Standard-OS-Funktion ist. Aber mir gefällt Ihre andere Lösung besser, es ist weniger Code und wahrscheinlich einfacher zu warten.
Josh
Oh, nicht ich meine nur, dass es magisch ist, weil ich noch nie mit Fifo-Pipes gespielt habe und es etwas ist, das nicht so oft verwendet wird wie andere Dinge. Obwohl es jetzt etwas zu lernen gibt. Auch die Wartung ist kein großes Problem. Dies wird für etwa einen Tag eingerichtet ist alles.
Mike Cooper
2

Nachdem ich über die Antworten nachgedacht hatte (insbesondere über die Idee von @Josh, sich die geänderten Zeiten anzusehen), versuchte ich, die Dateien von B auf C zu manipulieren war dort. Ich bin auf diese Lösung gestoßen. Diese Idee ist nicht meine, ich habe sie in der Google-Suche vor dieser Frage gefunden. Ich habe es früher verworfen, da Maschine B nicht über das findDienstprogramm verfügte.

Hängen Sie zuerst das entsprechende Verzeichnis in B in C ein, damit es als lokales Dateisystem angezeigt wird. Ich habe es benutzt sshfs(übrigens ein großartiges Werkzeug). 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 tatsächlich in C befindet, anstelle von sshfs, das von B bereitgestellt wurde).

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 muss noch fertiggestellt werden, daher kann ich nicht beurteilen, ob sie in Kombination mit dem Cron-Skript wirklich funktioniert, aber ich habe einige Dateien von Hand erstellt, sie geimpft und sie verschoben. drücke die Daumen

Bearbeiten: Dies funktioniert, obwohl es ursprünglich einige Fehler hatte, die jetzt korrigiert werden.

Mike Cooper
quelle
Das klingt nach einer großartigen Lösung
Josh
1

Mkfifo ist nicht nötig. Führen Sie auf Maschine B Folgendes aus:

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

Möglicherweise ist die Option -C von tar hilfreich.

Wenn Sie den Kopiervorgang auf Maschine A starten müssen, gehen Sie wie folgt vor:

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

Achten Sie jedoch auf korrekte Zitate.

Tuomassalo
quelle
0

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

Außerdem glaube ich, 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. Dies ist also nicht die beste Idee.

Gbarry
quelle
Ich muss nicht kopieren, sobald der gesamte Kopiervorgang abgeschlossen ist, da ich viele Dateien kopiere. Ich muss wissen, wann jede einzelne Datei fertig ist.
Mike Cooper