scp ou sftp copiam vários arquivos com um único comando

314

Eu gostaria de copiar arquivos de / para servidor remoto em diferentes diretórios. Por exemplo, eu quero executar esses 4 comandos de uma só vez.

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 é a maneira mais fácil de fazer isso?

user987654
fonte
14
Quando criei um script, tive que colocar a senha para cada comando. Posso evitá-lo?
user987654
11
Evite repetir a senha desta maneira: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd 21/15/15
O stackoverflow.com/a/23748561/874188 (indicado como duplicado deste) possui uma boa técnica adicional.
Tripleee 31/07
2
Eu sugiro que você dê uma olhada rsync, talvez ele possa ajudá-lo neste caso e em muitos casos futuros. Então, para evitar a digitação de senhas (sem falar várias vezes), você deve ler sobre sshchaves públicas / privadas, por exemplo, digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel
1
Exemplo com base na resposta do @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

Respostas:

421

Copie vários arquivos do remoto para o local:

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

Copie vários arquivos do local para o remoto:

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

Copie vários arquivos de remoto para remoto:

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

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

ios.id0
fonte
5
O primeiro comando omitiu o final "." E '{a, b, c}' é igual a \ {a, b, c \}.
Duleshi 5/05
11
Eu acho que o OP está tentando copiar vários arquivos em várias pastas locais para várias pastas remotas, esses exemplos não farão o trabalho, pois todos eles irão scp arquivos para ~ou ./apenas.
precisa saber é
20
Cuidado: não há espaços após as vírgulas nos chavetas. Passei apenas 10 minutos tentando descobrir por que meu comando não estava funcionando e foi por causa de espaços.
deepak
13
@duleshi {a, b, c} não é exatamente igual a \ {a, b, c \} ao copiar de remoto para local, pois o primeiro requer senha para cada arquivo, enquanto o segundo requer senha apenas uma vez.
Marcelo Ventura
15
@ MarceloVentura, @ duleshi: Além disso, gostaria de acrescentar que o uso \{a,b,c\}transferirá os arquivos em uma única conexão / lote (uma vez que eles serão expandidos no host remoto), enquanto o uso {a,b,c}abrirá várias conexões, e a sobrecarga é bastante perceptível ao transferir muitos arquivos
omninonsense
140

Do local para o servidor:

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

Do servidor para o local:

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

Gtr_py
fonte
6
Esta deve ser a resposta em cima, uma vez que o servidor não pedir a senha para cada arquivo :)
motagirl2
Não está funcionando no cliente no Ubuntu 18 (zsh). Não tenho certeza de onde isso deve funcionar. `` (venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.aaa: "/ usr / local / bin / kubectl /root/.kube/config" / tmp / root @ 172.29..xxx. senha do yyy: erro de protocolo: o nome do arquivo não corresponde à solicitação `` ''
jseguillon 26/04/19
3
@ motagirl2 A resposta principal não pede a senha de cada arquivo, desde que você esteja escapando dos colchetes com a barra invertida. Esta resposta me dá um erro que o arquivo não pode ser encontrado.
Plutão
1
@jseguillon Adicione a -Topção para suprimir esse erro.
Reponha Monica
1
as segundas obras um no meu máquinas, mas só que sem a opção -T
Richard DiSalvo
71

Você pode copiar diretórios inteiros usando a -ropção switch. Se você puder isolar seus arquivos no próprio diretório, poderá copiar tudo de uma vez.

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

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

então por exemplo

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

Ou, se houver apenas alguns deles, você pode usar:

scp 1.txt 2.txt 3.log user@remote-server:upload-path
Jiri Kremser
fonte
Isso funciona se meu destino for raiz e eu estiver executando o diretório etc como por exemplo: scp -r / backups / etc root @ linuxbox: / onde minha fonte é um diretório muito esparso com coisas como "hosts" e nginx / sites -disponível etc?
precisa saber é o seguinte
47

Como Jiri mencionou, você pode usar scp -r user@host:/some/remote/path /some/local/pathpara copiar arquivos recursivamente. Isso pressupõe que haja um único diretório contendo todos os arquivos que você deseja transferir (e nada mais).

No entanto, o SFTP fornece uma alternativa se você deseja transferir arquivos de vários diretórios diferentes e os destinos não são idênticos:

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

Isso usa a sintaxe "aqui doc" para definir uma sequência de comandos de entrada SFTP. Como alternativa, você pode colocar os comandos SFTP em um arquivo de texto e executarsftp user@host -b batchFile.txt

alev
fonte
3
Esta é a única resposta que realmente responde à pergunta. Obrigado. Estou pesquisando e analisando o scpmanual há muito tempo tentando encontrar esse recurso, e acho que o scp não o possui.
sudo
1
Essa parece ser a melhor e mais flexível resposta. Nota: Fiz uma viagem até perceber que precisava usar um caminho completo como em /home/vagrant/Code/vez de ~/Code/.
Ryan
Esta é a melhor resposta, apenas não se esqueça de adicionar - rpara diretórios
Chris_Rands
25

As respostas com {file1,file2,file3}funcionam apenas com o bash (no controle remoto ou localmente)

A maneira real é:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath
Vouze
fonte
1
Fantástico! Às vezes, uso conchas que não são do tipo bash e isso ajuda imensamente. Não apenas o caminho real, mas o caminho certo.
Paul B.
1
Globbing com {…, …, …}obras em muitas conchas, não apenas no Bash. No entanto, isso funciona em qualquer shell, então é claramente melhor.
Piotr Dobrogost
Precisa de mais citações. Esses caminhos podem conter espaços.
Amit Naidu
1
Aqui vamos nós! Eu voto positivo muitas vezes, mas só posso fazê-lo uma vez! Obrigado Vouze!
André Pacheco
17

Depois de jogar com o scp por um tempo, encontrei a solução mais robusta:

(Cuidado com as aspas simples e duplas)

Local para remoto:

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

Remoto para local:

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

Observe que o que for depois de "HOST:" será enviado para o controle remoto e analisado lá. Portanto, devemos garantir que eles não sejam processados ​​pelo shell local. É por isso que as aspas simples entram. As aspas duplas são usadas para manipular espaços nos nomes dos arquivos.

Se todos os arquivos estiverem no mesmo diretório, podemos usar * para corresponder a todos, como

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

Comparado ao uso da sintaxe "{}", que é suportada apenas por alguns shells, este é universal

eosphorox
fonte
Obrigado por ajudar com espaços nos nomes dos arquivos. Eu estava usando a abordagem {}, então também tive que escapar deles \ após citar.
Noumenon
3
Caso você queira usar o caractere til (~) para o diretório inicial em caminhos. Observe como ~ e / devem estar fora das aspas. `` scp -r [email protected]: '~ / "bin / set-vpn-kill-switch" ~ / "bin / flush-iptables"' ~ / "" `` `
Rob Waa
A {}sintaxe facilita a cópia de vários arquivos do mesmo diretório. Existe alguma maneira de fazer isso scp -rpara que "FILE1" "FILE2"possam ser caminhos relativos e não absolutos para os arquivos?
dtasev 6/01
15

A maneira mais simples é

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

Portanto, a lista {..} pode incluir diretórios (A, B e C aqui são diretórios; "1.txt" e "2.txt" são nomes de arquivos nesses diretórios).

Embora copie todos esses quatro arquivos em um diretório local - não tenho certeza se é isso que você deseja.

No caso acima, você terminará os arquivos remotos A / 1.txt, A / 2.txt, B / 3.txt e C / 4.txt copiados para um único diretório local, com nomes de arquivo ./1.txt, ./2.txt, ./3.txt e ./4.txt

Tagar
fonte
Isso não substitui o conteúdo de A / 1.txt pelo conteúdo de B / 1.txt na máquina local?
Yves Dorfsman
bom ponto .. exemplo ajustado (então agora não sobrescreveria) e descrição adicional. Obrigado.
Tagar
Expansões de chaves como essa são um recurso do Bash e não são portáveis ​​para, por exemplo, o POSIX sh.
Tripleee 31/07
1
@tripleee, obrigado. pode não ser posix, mas funciona não apenas no bash. Eu uso o ksh o tempo todo e funciona lá também.
Tagar 31/07/16
1
Você também pode misturar diretórios e arquivos fazendo o seguinte:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector 19/10/16
13

Problema : Copiando vários diretórios do servidor remoto para a máquina local usando um único comando SCP e mantendo cada diretório como está no servidor remoto.

Solução : o SCP pode fazer isso facilmente. Isso resolve o problema irritante de inserir a senha várias vezes ao usar o SCP com várias pastas. Consequentemente, isso também economiza muito tempo!

por exemplo

# 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: Motivado por esta ótima resposta: scp ou sftp copiam vários arquivos com um único comando


Com base nos comentários, isso também funciona bem no Git Bash no Windows

kmario23
fonte
3
PS não adicione espaços entre itens. ie \ {T1, T2, T3 \} ------> I desperdiçado dez minutos aqui ... lol
kenberkeley
1
Esta é a melhor resposta, porque quando você escapar das chaves será interpretado como um único comando, e ele não vai pedir a senha para cada transferência
Amaynut
@Amaynut sim, exatamente! Isso certamente poupa muito tempo e esforço :)
kmario23
12

Copie vários diretórios:

scp -r dir1 dir2 dir3 [email protected]:~/
yuliskov
fonte
A questão era como copiar do diretório remoto para o local, e não o contrário.
Tagar 19/04/16
5

Você pode fazer desta maneira:

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

Isso fará o download de todos os nomes de arquivos listados para qualquer diretório local em que você esteja.

Certifique-se de não colocar espaços entre cada nome de arquivo usando apenas uma vírgula ,.

J_rad
fonte
1
Isso é bom quando a extensão é a mesma. Pode ser escrito como /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}se os arquivos tivessem extensões diferentes. Observe para as pessoas do PowerShell (agora que a MS entrou na festa) que você precisa usar `para escapar:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev
3

NOTA: Peço desculpas antecipadamente por responder apenas a uma parte da pergunta acima. No entanto, achei esses comandos úteis para minhas necessidades atuais de unix.

Upload de arquivos específicos de uma máquina local para uma máquina remota:

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

Fazendo upload de um diretório inteiro de uma máquina local para uma máquina remota:

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

Fazendo download de um diretório inteiro de uma máquina remota para uma máquina local:

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

fat43r 80ard
fonte
3

No meu caso, estou restrito a usar apenas o comando sftp.
Então, eu tive que usar um arquivo em lote com o sftp. Eu criei um script como o seguinte. Isso pressupõe que você esteja trabalhando no diretório / tmp e deseja colocar os arquivos no sistema destdir_on_remote_system no sistema remoto. Isso também funciona apenas com um logon não interativo. Você precisa configurar chaves públicas / privadas para poder fazer login sem inserir uma senha. Mude conforme necessário.

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

seu comando funciona perfeitamente, mas também quero alterar o nome do arquivo ao enviar o local para o remoto. Eu escrevi um comando: - sshpass -p senha scp /path/to/file.txt root @ hostname: /path/newfile.txt

Mas dá erro que /path/newfile.txt: Nenhum arquivo ou diretório encontrado foi encontrado por favor me ajude nessa situação

Reshmi KC
fonte
Verifique se o diretório remoto hostname:/path/realmente existe e está acessível.
Amit Naidu
1

O scp usa ssh para transferência de dados com a mesma autenticação e fornece a mesma segurança que o ssh.

Uma prática recomendada aqui é implementar "SSH KEYS AND PUBLIC KEY AUTHENTICATION". Com isso, você pode escrever seus scripts sem se preocupar com autenticação. Simples assim.

Veja O QUE É SSH-KEYGEN

augusto
fonte
1

No caso específico em que todos os arquivos têm a mesma extensão, mas com sufixo diferente (por exemplo, número de arquivo de log), use o seguinte:

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

Isso copiará todos os arquivos com o nome some_log_file da pasta especificada no controle remoto, ou seja, some_log_file.1, some_log_file.2, some_log_file.3 ....

Guy Avraham
fonte
-1
scp remote:"[A-C]/[12].txt" local:
unxnut
fonte
obrigado, mas é apenas um exemplo, e o nome real do arquivo ou diretório é mais complexo. Mas eu tenho uma lista deles.
user987654
Você pode descrevê-los com uma expressão regular?
unxnut
É possível preservar a mesma estrutura de diretório no diretório de destino usando expressão regular?
user987654
1
Sim, você deve ser capaz de fazer isso com -ropção de scp. E você pode preservar outros atributos (como carimbo de data / hora) com a -popção
unxnut