Đây là một kịch bản mà chỉ những gì bạn yêu cầu.
Các yêu cầu
- Các tập tin được truyền phải có tổng kích thước nhỏ hơn một ngưỡng.
- Các tập tin phải được sửa đổi so với đích rsync.
- Nếu không phải tất cả các tệp có thể được chuyển, chỉ những tệp được sửa đổi gần đây nhất phải được chọn.
Các chi tiết
Nó sử dụng rsync --dry-run
để xây dựng một danh sách các tệp sẽ được chuyển (đây là các tệp đã được sửa đổi). Sau đó, nó sử dụng kết hợp du
và ls
để có được kích thước tệp và mtime. Sau đó, nó sắp xếp các tệp theo mtime và sau đó lặp lại chúng cho đến khi tổng kích thước vượt quá ngưỡng. Cuối cùng, nó gọi rsync một lần nữa chỉ với các tệp được sửa đổi gần đây nhất và tổng kích thước dưới ngưỡng.
Kịch bản hơi xấu, nhưng nó hoạt động. Một hạn chế lớn là nó phải được thực thi trên máy có chứa rsync từ thư mục. Nó có thể được sửa đổi để sử dụng ssh để sử dụng một thư mục từ xa, nhưng kích thước đó được để lại cho người đọc.
Cuối cùng, các rsync
tùy chọn được mã hóa cứng vào tập lệnh, nhưng đây là một thay đổi dễ dàng nếu bạn muốn chỉ định chúng trên dòng lệnh. Ngoài ra, toán để tính kích thước được thực hiện theo byte. Điều này có thể được thay đổi thành kilo / mega / gigabyte bằng cách sửa đổi cuộc gọi thành du và giảm ngưỡng theo cùng một yếu tố.
Sử dụng
./rsyncrecent.sh rsync-from-directory rsync-to-directory
trong đó rsync-from-directory
là một thư mục cục bộ và rsync-to-directory
là bất kỳ thư mục địa phương hoặc từ xa. Các tùy chọn mặc định được mã hóa cứng -avz
và ngưỡng mặc định được mã hóa cứng là 10GiB
.
Kịch bản
#!/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