Этот скрипт будет копировать произвольное количество входных каталогов на произвольное количество хостов параллельно с помощью фоновых заданий оболочки. Здесь я использовал cpio, потому что входные файлы легко разбить на части и передать по конвейеру , но вы также можете изменить это, чтобы использовать rsync --files-from
.
Использование: multi-cpio.sh <srcfile> <dstfile>
(требуются ssh-ключи для неинтерактивного входа в систему)
srcfile
содержит один каталог на строку, например:
/usr/share/man/man1
/usr/share/man/man3
/usr/share/man/man5
dstfile
содержит одну удаленную цель на строку, такую как:
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
См. Также http://rightsock.com/~kjw/Ramblings/tar_v_cpio.html для дополнительной ссылки на cpio и вдохновения для этого сценария.
Изменить: Альтернативный синтаксис только для одного src dst, без создания srcfile destfile:
multi-cpio.sh <(echo "/path/to/src") <(echo "user@host:/path/to/dest")