scp o sftp copiano più file con un singolo comando


314

Vorrei copiare file da / su server remoto in diverse directory. Ad esempio, voglio eseguire questi 4 comandi contemporaneamente.

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

Qual è il modo più semplice per farlo?


14
Quando ho creato uno script, ho dovuto inserire la password per ciascun comando. Posso evitarlo?
user987654,

11
Evitare di ripetere la password in questo modo: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd

stackoverflow.com/a/23748561/874188 (nominato come duplicato di questo) ha una bella tecnica aggiuntiva.
triplo

2
Suggerirei di dare un'occhiata rsync, forse ti può aiutare in questo caso e in molti casi imminenti. Quindi, per evitare di inserire password (figuriamoci più volte), dovresti leggere sshle chiavi pubbliche / private, ad esempio digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel

1
Esempio in base alla risposta @JohnMudd s': scp root@192.168.56.120:'/etc/openvpn/ca.crt /etc/openvpn/client/client0.crt /etc/openvpn/client/client0.key /etc/openvpn/client/ta.key' ./.
Eduardo Lucio,

Risposte:


421

Copia più file da remoto a locale:

$ scp your_username@remote.edu:/some/remote/directory/\{a,b,c\} ./

Copia più file da locale a remoto:

$ scp foo.txt bar.txt your_username@remotehost.edu:~
$ scp {foo,bar}.txt your_username@remotehost.edu:~
$ scp *.txt your_username@remotehost.edu:~

Copia più file da remoto a remoto:

$ scp your_username@remote1.edu:/some/remote/directory/foobar.txt \
your_username@remote2.edu:/some/remote/directory/

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


5
Il primo comando ha omesso la fine "." E '{a, b, c}' è uguale a \ {a, b, c \}.
duleshi,

11
Penso che OP stia provando a copiare più file in più cartelle locali in più cartelle remote, questi esempi non faranno il lavoro, poiché tutti eseguiranno lo scp dei file ~o ./solo.
aesede,

20
Attenzione: nessuno spazio dopo le virgole all'interno delle parentesi graffe. Ho appena trascorso 10 minuti cercando di capire perché il mio comando non funzionava ed era a causa degli spazi.
deepak,

13
@duleshi {a, b, c} non è esattamente uguale a \ {a, b, c \} quando si copia da remoto a locale, poiché il primo richiede la password per ciascun file mentre il secondo richiede la password una sola volta.
Marcelo Ventura,

15
@MarceloVentura, @duleshi: Inoltre, vorrei aggiungere che l'utilizzo \{a,b,c\}trasferirà i file in una singola connessione / batch (poiché verranno espansi sull'host remoto), mentre l'utilizzo {a,b,c}aprirà più connessioni e l'overhead è abbastanza evidente quando si trasferiscono molti file
omninonsense

140

Dal locale al server:

scp file1.txt file2.sh username@ip.of.server.copyto:~/pathtoupload

Dal server al locale:

scp -T username@ip.of.server.copyfrom:"file1.txt file2.txt" "~/yourpathtocopy"


6
Questa dovrebbe essere la risposta in alto, poiché il server non richiede la password per ogni file :)
motagirl2

Non funziona sul client su Ubuntu 18 (zsh). Non sono sicuro di dove dovrebbe funzionare. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. password di yyy: errore di protocollo: il nome file non corrisponde alla richiesta `` `
jseguillon

3
@ motagirl2 La risposta principale non richiede la password per ciascun file, purché si sfugga alle parentesi graffe con la barra rovesciata. Questa risposta mi dà un errore che non è stato possibile trovare il file.
Plutone,

1
@jseguillon Aggiungi l' -Topzione per eliminare quell'errore .
Ripristina Monica il

1
il secondo funziona sulle mie macchine ma solo senza l'opzione -T
Richard DiSalvo,

71

È possibile copiare intere directory con l'utilizzo di -rswitch, quindi se è possibile isolare i file nella propria directory, è possibile copiare tutto in una volta.

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

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

così per esempio

scp -r root@192.168.1.100:/var/log ~/backup-logs

O se ce ne sono solo alcuni, puoi usare:

scp 1.txt 2.txt 3.log user@remote-server:upload-path

Funziona se la mia destinazione è root e sto facendo la directory etc come ad esempio: scp -r / backups / etc root @ linuxbox: / dove la mia fonte è una directory molto scarna con cose come "hosts" e nginx / sites disponibile ecc?
Tomachi,

47

Come accennato da Jiri, puoi usare scp -r user@host:/some/remote/path /some/local/pathper copiare i file in modo ricorsivo. Ciò presuppone che esista una singola directory contenente tutti i file che si desidera trasferire (e nient'altro).

Tuttavia, SFTP offre un'alternativa se si desidera trasferire file da più directory diverse e le destinazioni non sono identiche:

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

Questo utilizza la sintassi "here doc" per definire una sequenza di comandi di input SFTP. In alternativa, è possibile inserire i comandi SFTP in un file di testo ed eseguiresftp user@host -b batchFile.txt


3
Questa è l'unica risposta che risponde effettivamente alla domanda. Grazie. Ho cercato su Google e analizzato il scpmanuale per troppo tempo cercando di trovare questa funzione, e immagino che scp non ce l'abbia.
sudo,

1
Questa sembra essere la risposta migliore e più flessibile. Nota: mi sono inciampato fino a quando mi sono reso conto che dovevo usare un percorso completo come /home/vagrant/Code/invece di ~/Code/.
Ryan,

Questa è la risposta migliore, non dimenticare di aggiungere le - rdirectory
Chris_Rands,

25

Le risposte con {file1,file2,file3}funzionano solo con bash (da remoto o localmente)

Il vero modo è:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath

1
Fantastico! A volte uso gusci non bash e questo aiuta incommensurabilmente. Non solo il modo reale, ma il modo giusto.
Paul B.

1
Sforzo con {…, …, …}opere in molte conchiglie, non solo in Bash. Tuttavia, questo funziona in qualsiasi shell, quindi è chiaramente migliore.
Piotr Dobrogost,

Ha bisogno di più citazioni. Tali percorsi possono contenere spazi.
Amit Naidu,

1
Eccoci! L'ho votato molte volte, ma posso farlo una volta sola! Grazie Vouze!
André Pacheco,

17

Dopo aver giocato con scp per un po 'ho trovato la soluzione più robusta:

(Attenzione alle virgolette singole e doppie)

Da locale a remoto:

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

Da remoto a locale:

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

Si noti che qualunque cosa dopo "HOST:" verrà inviata al telecomando e analizzata lì. Quindi dobbiamo assicurarci che non vengano elaborati dalla shell locale. Ecco perché arrivano le virgolette singole. Le virgolette doppie vengono utilizzate per gestire gli spazi nei nomi dei file.

Se i file sono tutti nella stessa directory, possiamo usare * per abbinarli tutti, ad esempio

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

Rispetto all'utilizzo della sintassi "{}" che è supportata solo da alcune shell, questa è universale


Grazie per l'aiuto con gli spazi nei nomi dei file. Stavo usando l'approccio {}, quindi ho dovuto scappare anche con \ dopo la quotazione.
Noumenon,

3
Nel caso in cui si desideri utilizzare il carattere tilde (~) per la propria directory home nei percorsi. Nota come ~ e / devono essere al di fuori delle virgolette. `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Rob Waa

La {}sintassi semplifica la copia di più file dalla stessa directory, esiste un modo per farlo in scp -rmodo che "FILE1" "FILE2"possano essere percorsi relativi e non percorsi assoluti ai file?
dtasev,

15

Il modo più semplice è

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

Quindi l'elenco {..} può includere directory (A, B e C qui sono directory; "1.txt" e "2.txt" sono nomi di file in quelle directory).

Sebbene copierebbe tutti questi quattro file in una directory locale - non sono sicuro che sia quello che volevi.

Nel caso precedente, i file remoti A / 1.txt, A / 2.txt, B / 3.txt e C / 4.txt verranno copiati in un'unica directory locale, con i nomi dei file ./1.txt, ./2.txt, ./3.txt e ./4.txt


Questo non sovrascriverebbe il contenuto di A / 1.txt con il contenuto di B / 1.txt sul computer locale?
Yves Dorfsman,

buon punto .. esempio corretto (quindi ora non sovrascrivere) e aggiunta descrizione. Grazie.
Tagar,

Le espansioni di parentesi graffe come questa sono una funzionalità di Bash e non portatili, ad esempio POSIX sh.
triplo

1
@tripleee, grazie. potrebbe non essere posix, ma funziona non solo in bash. Uso sempre ksh e funziona anche lì.
Tagar,

1
Puoi anche mescolare dir e file facendo:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector

13

Problema : copia di più directory dal server remoto al computer locale utilizzando un singolo comando SCP e mantenendo ogni directory così com'è nel server remoto.

Soluzione : SCP può farlo facilmente. Questo risolve il fastidioso problema di inserire la password più volte quando si utilizza SCP con più cartelle. Di conseguenza, anche questo fa risparmiare molto tempo!

per esempio

# 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 username@contact.server.de:/work/datasets/images/test/\{t1,t2,t3\}  .

PS: motivato da questa grande risposta: scp o sftp copiano più file con un solo comando


Sulla base dei commenti, anche questo funziona bene Git Bash su Windows


3
PS non aggiunge spazi tra gli elementi. cioè \ {t1, t2, t3 \} ------> Ho perso dieci minuti qui ... lol
kenberkeley il

1
Questa è la risposta migliore perché quando sfuggirai alle parentesi graffe verrà interpretato come un singolo comando da e non chiederà la password per ogni trasferimento
Amaynut

@Amaynut sì, esattamente! Ciò sicuramente fa risparmiare molto tempo e fatica :)
kmario23

12

Copia più directory:

scp -r dir1 dir2 dir3 admin@127.0.0.1:~/

la domanda era come copiare dalla directory remota a quella locale, non viceversa.
Tagar,

5

Puoi fare così:

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

Questo scaricherà tutti i nomi dei file elencati in qualunque directory locale ci si trovi.

Assicurati di non inserire spazi tra ciascun nome file usando solo una virgola ,.


1
Questo è buono quando l'estensione è la stessa. Potrebbe essere scritto come /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}se i file avessero estensioni diverse. Nota per le persone di PowerShell (ora che MS è entrata a far parte del gruppo) è necessario utilizzare `per fuggire invece:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev

3

NOTA: chiedo scusa in anticipo per aver risposto solo a una parte della domanda precedente. Tuttavia, ho trovato questi comandi utili per le mie attuali esigenze di Unix.

Caricamento di file specifici da un computer locale a un computer remoto:

~/Desktop/dump_files$ scp file1.txt file2.txt lab1.cpp etc.ext your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

Caricamento di un'intera directory da un computer locale a un computer remoto:

~$ scp -r Desktop/dump_files your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

Download di un'intera directory da un computer remoto a un computer locale:

~/Desktop$ scp -r your-user-id@remote.host.edu:Public/web/ Desktop/


3

Nel mio caso, sono limitato a usare solo il comando sftp.
Quindi, ho dovuto usare un file batch con sftp. Ho creato uno script come il seguente. Ciò presuppone che si stia lavorando nella directory / tmp e che si desideri inserire i file nel destdir_on_remote_system sul sistema remoto. Funziona anche con un login non interattivo. Devi impostare le chiavi pubbliche / private in modo da poter accedere senza inserire una password. Cambia se necessario.

#!/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

2

il tuo comando funziona perfettamente, ma voglio anche cambiare il nome del file durante l'invio da locale a remoto. Ho scritto un comando: - sshpass -p password scp /path/to/file.txt root @ hostname: /path/newfile.txt

Ma dà l'errore che /path/newfile.txt: nessun file o directory trovato, per favore, mi aiuti in questa situazione


Assicurarsi che la directory remota hostname:/path/esista effettivamente e sia accessibile.
Amit Naidu

1

scp usa ssh per il trasferimento dei dati con la stessa autenticazione e fornisce la stessa sicurezza di ssh.

Una best practice qui è quella di implementare "CHIAVI SSH E AUTENTICAZIONE CHIAVE PUBBLICA". Con questo, puoi scrivere i tuoi script senza preoccuparti dell'autenticazione. Semplice come quella.

Vedere CHE COS'È SSH-KEYGEN


1

Nel caso specifico in cui tutti i file hanno la stessa estensione ma con suffisso diverso (ad esempio il numero del file di registro) si utilizza quanto segue:

scp user_name@ip.of.remote.machine:/some/log/folder/some_log_file.* ./

Questo copierà tutti i file denominati some_log_file dalla cartella specificata all'interno del telecomando, cioè- some_log_file.1, some_log_file.2, some_log_file.3 ....


-1
scp remote:"[A-C]/[12].txt" local:

grazie, ma è solo un esempio e il nome effettivo del file o della directory è più complesso. Ma ne ho un elenco.
user987654,

Puoi descriverli con un'espressione regolare?
Unxnut

È possibile conservare la stessa struttura di directory nella directory di destinazione utilizzando l'espressione regolare?
user987654,

1
Sì, dovresti essere in grado di farlo con l' -ropzione scp. E puoi preservare altri attributi (come il timestamp) con l' -popzione.
Unxnut
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.