Como posso copiar vários arquivos sobre scp em um comando?

20

Eu tenho que transportar muitos arquivos de um PC para outro (ambos Linux). Eu gostaria de usar scppara isso, mas scpsó permite transferir um arquivo de cada vez.

Como posso fazer isso?

eu tenho

  • Não há possibilidade de usar rsync ou qualquer outro protocolo
  • Não há possibilidade de usar certificados sem senha (mas ter um certificado com uma senha)
  • Uma lista de arquivos a serem transferidos e uma lista com o caminho de destino dos arquivos no outro servidor
  • Os arquivos estão espalhados por vários diretórios, e nem todos os arquivos nos diretórios que eu quero copiar

Se possível, eu gostaria de compactar e descompactar transparentemente para economizar largura de banda!

Isso é possível?

Peter Smit
fonte

Respostas:

31

Use tar:

tar cvzf - -T list_of_filenames | ssh hostname tar xzf -
akira
fonte
2
Aqui está o formato do arquivo: "No modo c, o tar lerá os nomes a serem arquivados no nome do arquivo. O nome especial -C'' on a line by itself will cause the current directory to be changed to the directory specified on the following line. Names are terminated by newlines unless --null is specified. Note that --null also disables the special handling of lines containing -C ''."
Kousha
14

Eu gostaria de usar o scp para isso, mas o scp só permite transferir um arquivo de cada vez.

Tenho certeza de que isso não é verdade, pelo menos não para o scpcomando fornecido pelo OpenSSH incluído na maioria das distribuições Linux.

Eu uso com scp file1 file2 ... fileN user@host:/destination/directory/bastante frequência.

Para compactação transparente, o protocolo SSH tem isso incorporado e scppode usá-lo se você fornecer a -Copção na linha de comando. Para muitos arquivos pequenos semelhantes, você encontrará a opção tar + gz sugerida por akira obtém uma melhor compactação, pois pode fazer uso da semelhança entre esses arquivos, onde scpcomprime cada arquivo como uma entidade separada. Geralmente, prefiro usar o scp, pois é mais fácil retomar uma transferência parcial (ou, embora eu saiba que nessa situação o interlocutor não tem a opção), rsyncpois isso é ainda mais fácil de retomar e compartilhar toda a opção tar + gz vantagem de compactação.

David Spillett
fonte
Esta é a resposta certa, mas realmente transfere apenas um arquivo por vez. No entanto, ele fará pleno uso da largura de banda disponível e deve executar o mais rápido possível.
Benjamin Bannier
4

Não scp -r yourdir otherhost:/otherdirfunciona?

Tente isso então:

tar cfz - . | ssh otherhost "cd /mydir; tar xvzf -"

o z-flag para tar faz compressão. Ou você pode usar -C para ssh:

tar cf - . | ssh -C otherhost "cd /mydir; tar xvf -"
Jimmy Hedman
fonte
o que -Cfaz?
precisa
1
O problema é que tenho uma lista de arquivos. Os arquivos estão espalhados ao longo de um monte de diretórios, e nem todos os arquivos nos diretórios Eu quero copiar
Peter Smit
2
@ Nathan: -C é deixar o ssh fazer a compactação.
precisa
1

No RHEL5, aqui está a única maneira possível de garantir a cópia segura de uma lista de arquivos que contêm caracteres especiais (como um espaço). Faça um script de shell e inclua o seguinte:

FILE="/path/filename"
while read line; do
scp "$line" username@servername:/destination/
done < $FILE
Brian Thomas
fonte
0

Isso pode ser feito sem muitos problemas.

Eu simplesmente crio uma lista de arquivos com o nome do host ao lado de cada arquivo e o scp parece analisá-lo bem. ie

srchost=`hostname`
myfiles="${srchost}:~/.bashrc ${srchost}:~/.bash_profile ${srchost}:~/.vimrc ${srchost}:~/.viminfo ${srchost}:~/.toprc ${srchost}:~/.dir_colors"
scp -v $myfiles $HOME

Scp parece funcionar bem com essa sintaxe. Como eu tentei sem o nome do host ao lado de cada arquivo, ele falhou após o primeiro arquivo. Parece que me lembro de outra sintaxe que usei para isso antes e a publicarei assim que a localizar.

Ernie M.
fonte
Isso funciona, mas é bem lento - parece iniciar uma conexão para cada arquivo ... (eu vim aqui procurando uma solução para a cópia lenta ...) ~/pode ficar de fora - o SCP opera em relação ao diretório inicial. .. Se você tem uma lista de outro lugar $list: scp $(echo "$list"|sed "s/^/$srchost:/") local_destination(Isso irá quebrar nomes de arquivos com espaços)
Gert van den Berg