Berikut adalah skrip yang melakukan apa yang Anda minta.
Persyaratan
- File yang ditransfer harus berjumlah kurang dari ukuran ambang.
- File harus dimodifikasi dibandingkan dengan tujuan rsync.
- Jika tidak semua file dapat ditransfer, hanya file yang paling baru dimodifikasi harus dipilih.
Rinciannya
Ini digunakan rsync --dry-run
untuk membangun daftar file yang akan ditransfer (ini adalah file yang dimodifikasi). Kemudian menggunakan kombinasi du
dan ls
untuk mendapatkan ukuran dan waktu file. Ini kemudian mengurutkan file berdasarkan mtime dan kemudian loop di atasnya sampai ukuran total melebihi ambang batas. Akhirnya, ia memanggil rsync lagi hanya dengan file-file yang paling baru-baru ini dimodifikasi dan ukuran total di bawah ambang batas.
Skripnya agak jelek, tapi berhasil. Satu batasan besar adalah harus dijalankan pada mesin yang berisi direktori-rsync. Itu dapat dimodifikasi untuk menggunakan ssh untuk menggunakan remote dari-direktori, tetapi excersize diserahkan kepada pembaca.
Akhirnya, rsync
opsi tersebut dikodekan ke dalam skrip, tetapi ini adalah perubahan yang mudah jika Anda ingin menentukannya di baris perintah. Juga, matematika untuk menghitung ukuran dilakukan dalam byte. Ini dapat diubah menjadi kilo / mega / gigabytes dengan memodifikasi panggilan ke du dan mengurangi ambang dengan faktor yang sama.
Pemakaian
./rsyncrecent.sh rsync-from-directory rsync-to-directory
di mana rsync-from-directory
direktori lokal dan direktori rsync-to-directory
lokal atau jauh. Opsi default adalah hardcoded -avz
dan ambang default adalah hardcoded sebagai 10GiB
.
Naskah
#!/bin/bash
RSYNC=rsync
RSYNC_OPTS=-avz
THRESHOLD=10737418240
usage () {
echo >&2 "Usage: $0 from-location to-location"
exit 1
}
[ "$#" -eq 2 ] || usage
RSYNC_FROM=$1
RSYNC_TO=$2
echo "Fetching file list for $RSYNC $RSYNC_OPTS $RSYNC_FROM $RSYNC_TO"
# get list of changed files
FILES=`$RSYNC $RSYNC_OPTS --dry-run $RSYNC_FROM $RSYNC_TO | sed -n '/list$/,/^$/{/sending.*list$/ d ; /^$/ d ; /\/$/ d ;; p}'`
# reported files are relative to ..RSYNC_FROM, so rather than transforming filenames, lets just move there
pushd $RSYNC_FROM > /dev/null
# get modified time and sizes for all files
i=0
for FILE in $FILES
do
#strip first part of path so files are relative to RSYNC_FROM
FILE=${FILE#*/}
#FSIZE=`ls -l $FILE | cut -f5 -d' '`
FSIZE=`du -bs $FILE`
FMTIME=`ls -l --time-style=+%s $FILE | cut -f6 -d' '`
FLIST[$i]=`echo $FMTIME $FILE $FSIZE`
((i=$i+1))
done
# go back to original directory
popd > /dev/null
# sort list according to modified time
IFS=$'\n' FLIST=($(sort -rg <<<"${FLIST[*]}"))
max=$i
i=0
size=0
#NEWFLIST=''
# add up the files in mtime order until threshold is reached
for ((i=0; i<$max; i++))
do
s=`echo ${FLIST[$i]} | cut -f3 -d' '`
f=`echo ${FLIST[$i]} | cut -f2 -d' '`
((size=$size+$s))
if (( "$size" > "$THRESHOLD" ))
then
break
fi
NEWFLIST="$NEWFLIST $f"
echo $f >> /tmp/rsyncfilelist
done
$RSYNC $RSYNC_OPTS --dry-run $RSYNC_FROM --files-from=/tmp/rsyncfilelist $RSYNC_TO
rm /tmp/rsyncfilelist