scp, ohne vorhandene Dateien im Ziel zu ersetzen


158

Wie kopiere ich ein gesamtes Verzeichnis in ein Verzeichnis mit demselben Namen, ohne den Inhalt im Zielverzeichnis zu ersetzen? (stattdessen möchte ich den Inhalt des Zielordners ergänzen)


Ja, es ist ärgerlich, wenn ein nützliches Programm / Dienstprogramm nicht die Option "Wenn es nur könnte ..." hat! In diesem Fall "--noclobber"!
MikeW

Antworten:


139

Verwenden Sie rsyncund übergeben -uSie, wenn Sie nur Dateien aktualisieren möchten, die neuer im ursprünglichen Verzeichnis sind, oder --ignore-existingalle Dateien überspringen möchten, die bereits im Ziel vorhanden sind.

rsync -au /local/directory/ host:/remote/directory/
rsync -a --ignore-existing /local/directory/ host:/remote/directory/

(Beachten Sie das /auf der Quellseite: Ohne rsyncwürde es schaffen /remote/directory/directory.)


@Anthon Ich verstehe Ihren Kommentar nicht und sehe keine Antwort oder Kommentar von chandra. --ignore-existingfüge ohne zu ersetzen hinzu, welchen Datenverlust siehst du?
Gilles

Entschuldigung, ich habe nur Ihr erstes Beispiel betrachtet, in dem Sie Datenverlust haben können (und es ist meiner Meinung nach nicht das, wonach das OP gefragt hat), wenn Sie --ignore-existing data-loss einbeziehen, sollte dies nicht passieren.
Anthon

Dies hilft nicht, wenn das Remote-System nicht rsyncleicht verfügbar ist .... (Wie Win32-OpenSSH)
Gert van den Berg

@GertvandenBerg rsync ist ziemlich einfach unter Windows zu installieren, nicht schwerer als SSH.
Gilles

@Gilles: Stimmt, aber alle Optionen scheinen Cygwin-DLLs zu beinhalten ... (Der aktuelle Status des MS-Ports von OpenSSH ist so, dass das Aktivieren der Komprimierung auf scp ausreicht, um SCP zu beschädigen ...) (Rsync-Funktionalität über Win32 erhalten -OpenSSH scheint auch nicht trivial - hoffentlich verbessert sich das im Laufe der Zeit) (Solaris 10 ist das andere Beispiel, wo ein Paket von Drittanbietern --rsync-pathbenötigt wird)
Gert van den Berg

82

scp überschreibt die Dateien, wenn Sie über Schreibrechte verfügen.

Mit anderen Worten: Sie können diese scpDateien effektiv überspringen, indem Sie vorübergehend die Schreibberechtigungen für sie entfernen (wenn Sie also der Eigentümer der Dateien sind).


5
Danke dafür. War genau der Trick, den ich gesucht habe.
Saccharine

Stellen Sie sicher, dass Sie die Dateien zurückkopieren, und fügen Sie dazu ein * hinzu. Beispielscp -r user@server.com:/location/of/files/* /local/location/
Rick

1
finden . -type f -exec chown root: root {} \;
ling

1
In dem seltenen Fall, dass erwartet wird, dass nur einige der Dateien im Verzeichnis überschrieben werden (wenn sie nicht "geschützt" sind) und die Dateiberechtigungen zwischen den Dateien nicht einheitlich sind, funktioniert diese Lösung möglicherweise nicht. Ansonsten ist es recht einfach und effektiv.
sancho.s


12

Sie können nur neue Dateien nach Datum kopieren. Verwendenfind

scp  `find /data/*.gz -type f -mtime +7` USER@SERVER:/backup/

was bedeutet +7
Francis Kim

@FrancisKim bedeutet, vor 7 Tagen geändert. Diese Abfrage wählt also alle * .gz-Dateien aus, die innerhalb der letzten 7 Tage geändert wurden
Vadim Eremeev

4
Bedeutet +7 eigentlich nicht mehr als vor 7 Tagen?
Jeff H.

1
Ja, es bedeutet "vor mehr als 7 Tagen". Keine Ahnung, wer das befürwortet hat.
Stefan Reich

9

Wenn Sie den Inhalt der Zieldatei schreibgeschützt machen können:

find . -type f -exec chmod a-w '{}' \;

vor dem Ausführen scp(es wird sich beschweren und die vorhandenen Dateien überspringen).

Und ändern Sie sie anschließend zurück ( chmod +wum einen auf umask basierenden Wert zu erhalten). Wenn die Dateien nicht alle Schreibrechte gemäß Ihrer umask haben, müssten Sie die Rechte irgendwie speichern, damit Sie sie wiederherstellen können.

(Gilles 'Antwort überschreibt vorhandene Dateien, wenn sie lokal neuer sind. Ich habe auf diese Weise wertvolle Daten verloren. Verstehe nicht, warum diese falsche und schädliche Antwort so viele Stimmen hat.)


2
Ich verstehe es nicht: Wie sind rsync --ignore-existingSie dazu gekommen, Daten zu verlieren?
Gilles

4
Ich habe den Fehler mit find: missing argument to '-exec'diesem Befehl und stattdessen musste benutzen find . -type f -exec chmod a-w {} \;. Mein Linux ist schlecht, ymmv.
wpearse

Dies ist eine bessere und sicherere Antwort. Der richtige Befehl zum Ändern der Berechtigung lautet wie @wpearse erwähnt:find . -type f -exec chmod a-w {} \;
Amir

6

Ich hatte eine ähnliche Aufgabe, in meinem Fall konnte ich nicht verwenden rsync, csyncoder FUSE , weil meine Lagerung nur SFTP hat. rsyncDatum und Uhrzeit der Datei konnten nicht geändert werden. Einige andere Dienstprogramme (z. B. csync) haben mir andere Fehler angezeigt : " Zeitversatz der temporären Datei konnte nicht erkannt werden ".

Wenn Sie Zugriff auf den Storage-Server haben, können Sie diesen hier einfach als Daemon installieren openssh-serveroder starten rsync.

In meinem Fall konnte ich das nicht und die Lösung war: lftp . lftpDie Verwendung von für die Synchronisierung ist nachstehend aufgeführt:

lftp -c "open -u login,password sftp://sft.domain.tld/; \
    mirror -c --verbose=9 -e -R -L /srs/folder /rem/folder"

/src/folder- ist der Ordner auf meinem PC, /rem/folder- ist sftp://sft.domain.tld/rem/folder.

Manpages finden Sie unter folgendem Link: http://lftp.yar.ru/lftp-man.html


6

Um eine ganze Reihe von Dateien zu kopieren, ist es schneller, sie zu tarieren. Mit -k verhindern Sie außerdem, dass tar Dateien überschreibt, wenn es auf dem Zielsystem entpackt wird.

tar -c <source-dir> | ssh <name>@<host> 'tar -kxzf - -C <target-dir>' 

1
Es wird eine Remote-Verbindung hergestellt. Zuerst ist es tar die Quelle, leitet es in die SSH-Verbindung und entpackt es auf dem Remote-System.
Huembi

-1

scpüberschreibt Dateien und es gibt keinen Schalter, um dies zu stoppen, aber Sie können Dinge aus dem Weg kopieren, scp ausführen und dann die vorhandenen Dateien zurückkopieren. Beispiele:

  1. Kopieren Sie alle vorhandenen Dateien aus dem Weg

    mkdir original_files ; cp -r * original_files/
    
  2. Kopieren Sie alles mit scp

    scp -r user@server:dir/* ./
    
  3. Kopieren Sie die Originaldateien über alles, was scp überschrieben hat:

    cp -r original_files/* ./
    

3
Diese Methode ist nicht hilfreich, wenn Sie versuchen, Dateien von einer Fernbedienung abzurufen und dort fortzufahren, wo Sie aufgehört haben. Dh wenn der ganze Zweck darin besteht, Zeit zu sparen.
Oliver Williams

-1

Eine andere Möglichkeit, dies zu erreichen, besteht darin, lsim Zielordner Folgendes zu tun :

Im Remote-Zielordner:

ls | awk '{print "mv " $1 " ../copied_data/"}' > mv_copied_data
scp mv_copied_data user@source.server.com:/path/to/source/folder

An der Quelle:

cd /path/to/source/folder
chmod 777 mv_copied_data
./mv_copied_data

Am Bestimmungsort:

scp -r user@source.server.com:/path/to/source/folder /path/to/destination/foldeer

Bitte tu das nicht. 1. Analysiere ls nicht . 2. Die Antwort ist gefährlich, wenn ein Dateiname - >Leerzeichen oder andere Sonderzeichen enthält . 3. Erstellen Sie eine for-Schleife in einem Python-Skript. Das Generieren eines Programms zur Laufzeit ist aus vielen Gründen schwierig und schwierig (selbst wenn es von professionellen Programmierern durchgeführt wird). Ein Shell-Skript zu generieren ist noch schlimmer - eine schreckliche Idee.
Ignis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.