Copie várias fontes para vários destinos simultaneamente

2

Suponha que eu precise copiar arquivos

~/path/to/file a user@remote:/path/to/file

~/path/to/another/file a user@remote:/path/to/another/file

~/path/alternative a user@remote:/path/alternative

Existe uma maneira de fazer isso usando rsync ou scp ?

Eu tentei rsync ~/path/{to/file,to/another/file,alternative} user@remote:/path

Mas não é uma opção se eu precisar copiar para outro destino como another_path .

Copiar arquivo por arquivo é muito longo se eu precisar copiar pelo menos 20 arquivos.

    
por Nemoden 25.11.2014 / 07:18

2 respostas

1

Se você deseja transferir uma seleção de arquivos via rsync, ou seja, não o diretório inteiro, incluindo o conteúdo, a melhor maneira de fazer isso é usando a opção --files-from do rsync. Coloque os nomes de caminho dos arquivos que você deseja transferir, relativos ao diretório de origem especificado. Veja a manpage do rsync para informações mais detalhadas.

    
por 26.11.2014 / 10:27
0

Este script irá copiar um número arbitrário de diretórios de entrada, para um número arbitrário de hosts, em paralelo através do uso de trabalhos em segundo plano do shell. Aqui eu usei cpio porque é fácil dividir e canalizar os arquivos de entrada, mas você pode modificar isso para usar rsync --files-from também.

Uso: multi-cpio.sh <srcfile> <dstfile> (requer ssh-keys para login não interativo)

srcfile contém um diretório por linha, como:

/usr/share/man/man1
/usr/share/man/man3
/usr/share/man/man5

dstfile contém um destino remoto por linha, como:

user@host:/tmp/a
user@host:/tmp/b
user@host:/tmp/c

... e a fonte para multi-cpio.sh :

#!/bin/bash 

SRCLIST=$1
DSTLIST=$2

# create temporary files, safely, in /tmp with mcpio prefix
TEMP='tempfile -p mcpio'

# loop over input file and create a list of all files to be copied
for I in 'cat $SRCLIST' ; do
  find $I -depth -print >>$TEMP
done

# split the file into CPU count + factor
# set to '4' here, seems like ~6x CPIO will max my 1Gb Ethernet link to ~800Mbps in atop
SPLITCOUNT= $(( $( wc -l $TEMP | cut -d' ' -f1) / $(( $( grep processor /proc/cpuinfo | wc -l ) + 4 )) ))
split -l $SPLITCOUNT $TEMP $TEMP 


# nested loops, for each target and for each chunk, start a background copy


for DEST in 'cat $DSTLIST' ; do
  # this selects the "user@host" from user@host:/target/path
  HOST=$(expr substr $DEST 1 $(($(expr index $DEST :)-1)))
  # this selects the "/target/path" from user@host:/target/path
  DIR=$(expr substr $DEST $(($(expr index $DEST :)+1)) $(expr length $DEST))

  # loop over all the split tempfiles with ${TEMP}??
  for I in ${TEMP}?? ; do
   # use cpio in copy-out mode to stream the files through ssh
   # then ensure the target is in place in the remote host, cd into it,
   # and copy-in the files.
   # note the '&' at the end backgrounds this command, so the loop
   # will continue and generate more concurrent background jobs
   cat $I | cpio -o | ssh $HOST \
     "mkdir $DIR ; cd $DIR && cpio -idum --no-absolute-filenames" & 
   # sleep for a second before the next spawn to allow for ssh auth
   #  and so sshd doesn't start dropping new sessions
   sleep 1
  done
done

# cleanup the tempfiles
rm ${TEMP}??
rm $TEMP

Veja também link para referência adicional sobre o cpio e a inspiração para esse script.

Edit: Sintaxe alternativa para apenas um src dst, sem criar o arquivo destr do srcfile:

multi-cpio.sh <(echo "/path/to/src") <(echo "user@host:/path/to/dest")
    
por 26.11.2014 / 14:11