web-dev-qa-db-ja.com

複数のソースを複数の宛先に同時にコピーする

ファイルをコピーする必要があるとしましょう

~/path/to/fileからuser@remote:/path/to/file

~/path/to/another/fileからuser@remote:/path/to/another/file

~/path/alternativeからuser@remote:/path/alternative

rsyncまたはscpを使用してこれを行う方法はありますか?

rsync ~/path/{to/file,to/another/file,alternative} user@remote:/pathを試しました

しかし、another_pathのような別の宛先にコピーする必要がある場合はオプションではありません。

少なくとも20個のファイルをコピーする必要がある場合、ファイルごとのコピーは長すぎます。

2
Nemoden

選択したファイルをrsync経由で転送する場合、つまりコンテンツを含むディレクトリ全体を転送する場合は、rsyncの--files-fromオプションを使用するのが最善の方法です。指定したソースディレクトリを基準にして、転送するファイルのパス名を配置します。詳細については、rsyncのマンページを参照してください。

1
wurtel

このスクリプトは、シェルのバックグラウンドジョブを使用して、任意の数の入力ディレクトリを任意の数のホストに並行してコピーします。ここでは、入力ファイルを分割してパイプするのが簡単なため、cpioを使用しましたが、これを変更してrsync --files-fromを使用することもできます。

使用法:multi-cpio.sh <srcfile> <dstfile>(非対話型ログインにはsshキーが必要です)

srcfileには、次のように1行に1つのディレクトリが含まれます。

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

dstfileには、次のように、行ごとに1つのリモートターゲットが含まれます。

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

...そして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

追加のcpioリファレンスとこのスクリプトのインスピレーションについては、 http://rightsock.com/~kjw/Ramblings/tar_v_cpio.html も参照してください。

編集:srcfile destfileを作成せずに、1つのsrcdstの代替構文:

multi-cpio.sh <(echo "/path/to/src") <(echo "user@Host:/path/to/dest")
0
glallen