scp oder sftp kopieren mehrere Dateien mit einem einzigen Befehl

314

Ich möchte Dateien von / auf einen Remote-Server in verschiedenen Verzeichnissen kopieren. Zum Beispiel möchte ich diese 4 Befehle gleichzeitig ausführen.

scp remote:A/1.txt local:A/1.txt
scp remote:A/2.txt local:A/2.txt
scp remote:B/1.txt local:B/1.txt
scp remote:C/1.txt local:C/1.txt

Was ist der einfachste Weg, das zu tun?

user987654
quelle
14
Als ich ein Skript erstellte, musste ich für jeden Befehl ein Passwort eingeben. Kann ich das vermeiden?
user987654
11
Vermeiden Sie es, das Passwort folgendermaßen zu wiederholen: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" lokal: ./
JohnMudd
stackoverflow.com/a/23748561/874188 (nominiert als Duplikat von diesem) hat eine nette zusätzliche Technik.
Tripleee
2
Ich würde vorschlagen, dass Sie einen Blick darauf werfen rsync, vielleicht kann es Ihnen in diesem Fall und vielen bevorstehenden Fällen helfen. Um die Eingabe von Passwörtern zu vermeiden (geschweige denn mehrmals), sollten Sie sich über sshöffentliche / private Schlüssel
informieren
1
Beispiel basierend auf der Antwort von @JohnMudd : scp [email protected]:'/etc/openvpn/ca.crt /etc/openvpn/client/client0.crt /etc/openvpn/client/client0.key /etc/openvpn/client/ta.key' ./.
Eduardo Lucio

Antworten:

420

Kopieren Sie mehrere Dateien von remote nach lokal:

$ scp [email protected]:/some/remote/directory/\{a,b,c\} ./

Kopieren Sie mehrere Dateien von lokal nach remote:

$ scp foo.txt bar.txt [email protected]:~
$ scp {foo,bar}.txt [email protected]:~
$ scp *.txt [email protected]:~

Kopieren Sie mehrere Dateien von Remote zu Remote:

$ scp [email protected]:/some/remote/directory/foobar.txt \
[email protected]:/some/remote/directory/

Quelle: http://www.hypexr.org/linux_scp_help.php

ios.id0
quelle
5
Der erste Befehl ließ ein Ende "." Weg und '{a, b, c}' ist gleich \ {a, b, c \}.
Duleshi
11
Ich denke, OP versucht, mehrere Dateien in mehreren lokalen Ordnern in mehrere Remote-Ordner zu kopieren. Diese Beispiele erledigen den Job nicht, da sie alle Dateien in ~oder ./nur scp-Dateien erstellen .
Aesede
20
Achtung: Keine Leerzeichen nach den Kommas in den geschweiften Klammern. Ich habe gerade 10 Minuten damit verbracht herauszufinden, warum mein Befehl nicht funktionierte und es an Leerzeichen lag.
Deepak
13
@duleshi {a, b, c} ist beim Kopieren von remote nach lokal nicht genau gleich \ {a, b, c \}, da für das erste Kennwort für jede Datei erforderlich ist, während für das zweite Kennwort nur einmal erforderlich ist.
Marcelo Ventura
15
@MarceloVentura, @duleshi: Außerdem möchte ich hinzufügen, dass mit using \{a,b,c\}die Dateien in einer einzigen Verbindung / einem Stapel übertragen werden (da sie auf dem Remote-Host erweitert werden), während mit using {a,b,c}mehrere Verbindungen geöffnet werden und der Overhead gleich ist ziemlich auffällig beim Übertragen vieler Dateien
Omninonsense
140

Vom lokalen zum Server:

scp file1.txt file2.sh [email protected]:~/pathtoupload

Vom Server zum lokalen:

scp -T [email protected]:"file1.txt file2.txt" "~/yourpathtocopy"

Gtr_py
quelle
6
Dies sollte die Antwort oben sein, da der Server nicht für jede Datei nach dem Passwort fragt :)
motagirl2
Funktioniert nicht auf dem Client unter Ubuntu 18 (zsh). Ich bin mir nicht sicher, wo das funktionieren soll. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. yyys Passwort: Protokollfehler: Dateiname stimmt nicht mit Anfrage überein `` `
jseguillon
3
@ motagirl2 Die oberste Antwort fragt nicht nach dem Passwort für jede Datei, solange Sie den geschweiften Klammern mit dem Backslash entkommen. Diese Antwort gibt mir einen Fehler, dass die Datei nicht gefunden werden kann.
Pluto
1
@jseguillon Fügen Sie die -TOption hinzu, um diesen Fehler zu unterdrücken.
Stellen Sie Monica
1
Der zweite funktioniert auf meinen Maschinen, aber nur ohne die Option -T
Richard DiSalvo
71

Sie können ganze Verzeichnisse mit -rswitch kopieren. Wenn Sie also Ihre Dateien in ein eigenes Verzeichnis isolieren können, können Sie alles auf einmal kopieren.

scp -r ./dir-with-files user@remote-server:upload-path

scp -r user@remote-server:path-to-dir-with-files download-path

so zum Beispiel

scp -r [email protected]:/var/log ~/backup-logs

Oder wenn es nur wenige davon gibt, können Sie Folgendes verwenden:

scp 1.txt 2.txt 3.log user@remote-server:upload-path
Jiri Kremser
quelle
Funktioniert dies, wenn mein Ziel root ist und ich das Verzeichnis etc wie zum Beispiel scp -r / backups / etc root @ linuxbox: / mache, wobei meine Quelle ein sehr spärliches Verzeichnis mit Dingen wie "hosts" und nginx / sites ist -verfügbar etc?
Tomachi
47

Wie Jiri bereits erwähnt hat, können Sie scp -r user@host:/some/remote/path /some/local/pathDateien rekursiv kopieren. Dies setzt voraus, dass es ein einziges Verzeichnis gibt, das alle Dateien enthält, die Sie übertragen möchten (und sonst nichts).

SFTP bietet jedoch eine Alternative, wenn Sie Dateien aus mehreren verschiedenen Verzeichnissen übertragen möchten und die Ziele nicht identisch sind:

sftp user@host << EOF
  get /some/remote/path1/file1 /some/local/path1/file1
  get /some/remote/path2/file2 /some/local/path2/file2
  get /some/remote/path3/file3 /some/local/path3/file3
EOF

Dies verwendet die Syntax "here doc" , um eine Folge von SFTP-Eingabebefehlen zu definieren. Alternativ können Sie die SFTP-Befehle in eine Textdatei einfügen und ausführensftp user@host -b batchFile.txt

Alev
quelle
3
Dies ist die einzige Antwort, die die Frage tatsächlich beantwortet. Vielen Dank. Ich habe viel scpzu lange gegoogelt und das Handbuch analysiert , um diese Funktion zu finden, und ich denke, scp hat sie nicht.
Sudo
1
Dies scheint die beste und flexibelste Antwort zu sein. Hinweis: Ich wurde gestolpert, bis mir klar wurde, dass ich einen vollständigen Pfad wie /home/vagrant/Code/anstelle von verwenden musste ~/Code/.
Ryan
Dies ist die beste Antwort, vergessen Sie nicht, - rfür Verzeichnisse hinzuzufügen
Chris_Rands
25

Die Antworten mit {file1,file2,file3}funktionieren nur mit Bash (auf Remote oder lokal)

Der wahre Weg ist:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath
Vouze
quelle
1
Fantastisch! Ich benutze manchmal Nicht-Bash-Muscheln und das hilft unermesslich. Nicht nur der richtige Weg, sondern der richtige Weg.
Paul B.
1
Globbing mit {…, …, …}Arbeiten in vielen Muscheln, nicht nur in Bash. Dies funktioniert jedoch in jeder Shell und ist daher deutlich besser.
Piotr Dobrogost
Benötigt mehr Zitate. Diese Pfade können Leerzeichen enthalten.
Amit Naidu
1
Na, bitte! Ich würde das viele Male positiv bewerten, aber ich kann es nur einmal tun! Vielen Dank, Vouze!
André Pacheco
17

Nachdem ich eine Weile mit scp gespielt habe, habe ich die robusteste Lösung gefunden:

(Achten Sie auf einfache und doppelte Anführungszeichen)

Lokal zu Remote:

scp -r "FILE1" "FILE2" HOST:'"DIR"'

Remote zu lokal:

scp -r HOST:'"FILE1" "FILE2"' "DIR"

Beachten Sie, dass alles nach "HOST:" an die Fernbedienung gesendet und dort analysiert wird. Wir müssen also sicherstellen, dass sie nicht von der lokalen Shell verarbeitet werden. Aus diesem Grund werden einfache Anführungszeichen verwendet. Die doppelten Anführungszeichen werden verwendet, um Leerzeichen in den Dateinamen zu behandeln.

Wenn sich alle Dateien im selben Verzeichnis befinden, können wir * verwenden, um sie alle abzugleichen, z

scp -r "DIR_IN"/*.txt HOST:'"DIR"'
scp -r HOST:'"DIR_IN"/*.txt' "DIR"

Im Vergleich zur Verwendung der "{}" - Syntax, die nur von einigen Shells unterstützt wird, ist diese universell

Eosphorox
quelle
Vielen Dank für Ihre Hilfe bei Leerzeichen in den Dateinamen. Ich habe den Ansatz {} verwendet, also musste ich ihnen nach dem Zitieren auch mit \ entkommen.
Noumenon
3
Falls Sie das Tilde-Zeichen (~) für Ihr Home-Verzeichnis in Pfaden verwenden möchten. Beachten Sie, wie die ~ und / außerhalb der Anführungszeichen stehen müssen. `` `scp -r [email protected]: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" `` `
Rob Waa
Die {}Syntax erleichtert das Kopieren mehrerer Dateien aus demselben Verzeichnis. Gibt es eine Möglichkeit, dies zu tun, scp -rsodass es "FILE1" "FILE2"sich um relative Pfade und nicht um absolute Pfade zu den Dateien handeln kann?
dtasev
15

Der einfachste Weg ist

local$ scp remote:{A/1,A/2,B/3,C/4}.txt ./

Die Liste {..} kann also Verzeichnisse enthalten (A, B und C sind hier Verzeichnisse; "1.txt" und "2.txt" sind Dateinamen in diesen Verzeichnissen).

Obwohl es alle diese vier Dateien in ein lokales Verzeichnis kopieren würde - nicht sicher, ob Sie das wollten.

Im obigen Fall werden die Remote-Dateien A / 1.txt, A / 2.txt, B / 3.txt und C / 4.txt in ein einzelnes lokales Verzeichnis mit den Dateinamen ./1.txt kopiert. ./2.txt, ./3.txt und ./4.txt

Tagar
quelle
Würde dies nicht den Inhalt von A / 1.txt mit dem Inhalt von B / 1.txt auf dem lokalen Computer überschreiben?
Yves Dorfsman
guter Punkt .. angepasstes Beispiel (so dass es jetzt nicht überschrieben wird) und Beschreibung hinzugefügt. Vielen Dank.
Tagar
Klammererweiterungen wie diese sind eine Bash-Funktion und nicht auf POSIX portierbar sh.
Tripleee
1
@ Tripleee, danke. Es ist vielleicht kein Posix, aber es funktioniert nicht nur in Bash. Ich benutze ksh die ganze Zeit und es funktioniert auch dort.
Tagar
1
Sie können auch Verzeichnisse und Dateien mischen, indem Sie Folgendes tun:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector
13

Problem : Kopieren mehrerer Verzeichnisse vom Remoteserver auf den lokalen Computer mit einem einzigen SCP-Befehl und Beibehalten jedes Verzeichnisses auf dem Remoteserver.

Lösung : SCP kann dies problemlos tun. Dies löst das lästige Problem der mehrfachen Eingabe eines Kennworts bei Verwendung von SCP mit mehreren Ordnern. Das spart somit auch viel Zeit!

z.B

# copies folders t1, t2, t3 from `test` to your local working directory
# note that there shouldn't be any space in between the folder names;
# we also escape the braces.
# please note the dot at the end of the SCP command

~$ cd ~/working/directory
~$ scp -r [email protected]:/work/datasets/images/test/\{t1,t2,t3\}  .

PS: Motiviert durch diese großartige Antwort: scp oder sftp kopieren mehrere Dateien mit einem einzigen Befehl


Basierend auf den Kommentaren funktioniert dies auch in Git Bash unter Windows

kmario23
quelle
3
PS Fügen Sie keine Leerzeichen zwischen Elementen hinzu. dh \ {t1, t2, t3 \} ------> Ich habe hier zehn Minuten verschwendet ... lol
kenberkeley
1
Dies ist die beste Antwort, denn wenn Sie den geschweiften Klammern entkommen, wird sie von als einzelner Befehl interpretiert und es wird nicht bei jeder Übertragung nach dem Passwort
gefragt
@Amaynut ja genau! Das spart sicherlich viel Zeit und Mühe :)
kmario23
12

Kopieren Sie mehrere Verzeichnisse:

scp -r dir1 dir2 dir3 [email protected]:~/
Yuliskov
quelle
Die Frage war, wie man von einem entfernten Verzeichnis in ein lokales kopiert, nicht umgekehrt.
Tagar
5

Sie können dies folgendermaßen tun:

scp hostname@serverNameOrServerIp:/path/to/files/\\{file1,file2,file3\\}.fileExtension ./

Dadurch werden alle aufgelisteten Dateinamen in das lokale Verzeichnis heruntergeladen, in dem Sie sich befinden.

Stellen Sie sicher, dass zwischen den Dateinamen keine Leerzeichen stehen. Verwenden Sie nur ein Komma ,.

J_rad
quelle
1
Dies ist gut, wenn die Erweiterung identisch ist. Es könnte so geschrieben werden, als /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}hätten die Dateien unterschiedliche Erweiterungen. Hinweis für PowerShell-Benutzer (jetzt, da MS der Gruppe beigetreten ist), müssen Sie `stattdessen verwenden , um zu entkommen:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
Benutzer Gruppe
3

HINWEIS: Ich entschuldige mich im Voraus für die Beantwortung nur eines Teils der obigen Frage. Ich fand diese Befehle jedoch nützlich für meine aktuellen Unix-Anforderungen.

Hochladen bestimmter Dateien von einem lokalen Computer auf einen Remotecomputer:

~/Desktop/dump_files$ scp file1.txt file2.txt lab1.cpp etc.ext [email protected]:Folder1/DestinationFolderForFiles/

Hochladen eines gesamten Verzeichnisses von einem lokalen Computer auf einen Remotecomputer:

~$ scp -r Desktop/dump_files [email protected]:Folder1/DestinationFolderForFiles/

Herunterladen eines gesamten Verzeichnisses von einem Remotecomputer auf einen lokalen Computer:

~/Desktop$ scp -r [email protected]:Public/web/ Desktop/

fat43r 80ard
quelle
3

In meinem Fall kann ich nur den Befehl sftp verwenden.
Also musste ich eine Batchdatei mit sftp verwenden. Ich habe ein Skript wie das folgende erstellt. Dies setzt voraus, dass Sie im Verzeichnis / tmp arbeiten und die Dateien im destdir_on_remote_system auf dem Remote-System ablegen möchten. Dies funktioniert auch nur mit einem nicht interaktiven Login. Sie müssen öffentliche / private Schlüssel einrichten, damit Sie sich ohne Eingabe eines Kennworts anmelden können. Ändern Sie nach Bedarf.

#!/bin/bash

cd /tmp
# start script with list of files to transfer
ls -1 fileset1* > batchfile1
ls -1 fileset2* >> batchfile1

sed -i -e 's/^/put /' batchfile1
echo "cd destdir_on_remote_system" > batchfile
cat batchfile1 >> batchfile
rm batchfile1

sftp -b batchfile user@host
dminear
quelle
2

Ihr Befehl funktioniert einwandfrei, aber ich möchte auch den Dateinamen ändern, während Sie lokal an remote senden. Ich habe einen Befehl geschrieben: - sshpass -p Passwort scp /path/to/file.txt root @ Hostname: /path/newfile.txt

Aber es gibt einen Fehler, dass /path/newfile.txt: Keine solche Datei oder Verzeichnis gefunden plz helfen mir in dieser Situation

Reshmi KC
quelle
Stellen Sie sicher, dass das Remote-Verzeichnis hostname:/path/tatsächlich vorhanden und zugänglich ist.
Amit Naidu
1

scp verwendet ssh für die Datenübertragung mit derselben Authentifizierung und bietet dieselbe Sicherheit wie ssh.

Eine bewährte Methode ist hier die Implementierung von "SSH KEYS AND PUBLIC KEY AUTHENTICATION". Mit dieser Funktion können Sie Ihre Skripte schreiben, ohne sich um die Authentifizierung kümmern zu müssen. So einfach ist das.

Siehe WAS IST SSH-KEYGEN?

August
quelle
1

In dem speziellen Fall, in dem alle Dateien dieselbe Erweiterung haben, aber ein anderes Suffix haben (z. B. die Anzahl der Protokolldateien), verwenden Sie Folgendes:

scp [email protected]:/some/log/folder/some_log_file.* ./

Dadurch werden alle Dateien mit dem Namen some_log_file aus dem angegebenen Ordner auf der Remote-Datei kopiert, z. B. some_log_file.1, some_log_file.2, some_log_file.3 ....

Guy Avraham
quelle
-1
scp remote:"[A-C]/[12].txt" local:
unxnut
quelle
danke, aber es ist nur ein Beispiel, und der tatsächliche Datei- oder Verzeichnisname ist komplexer. Aber ich habe eine Liste von ihnen.
user987654
Können Sie diese durch einen regulären Ausdruck beschreiben?
Unxnut
Ist es möglich, dieselbe Verzeichnisstruktur im Zielverzeichnis mithilfe eines regulären Ausdrucks beizubehalten?
user987654
1
Ja, Sie sollten dies mit der -rOption tun können scp. Und Sie können andere Attribute (wie Zeitstempel) mit -pOption beibehalten .
Unxnut