rsync новый x ГБ

Это похоже xinput вывод отклонений в файл, но не отклоняет вывод к терминалу. Достигнуть этого, вероятно xinput используйте системный вызов

int isatty(int fd)

проверять, относится ли filedescriptor, который будет открыт, к терминалу или нет.

Я наткнулся на то же явление только что с названной программой dpic. После того, как я изучил источник и некоторую отладку, я удалил строки, связанные с isatty и все работало как ожидалось снова.

Но я соглашаюсь с Вами, что этот опыт является очень тревожащим ;)

8
04.12.2013, 19:41
3 ответа

Вот сценарий, который делает, что Вы попросили.

Требования

  • Переданные файлы должны составить меньше, чем пороговый размер.
  • Файлы должны быть изменены по сравнению с rsync местом назначения.
  • Если не все файлы могут быть переданы, только последний раз измененные файлы должны быть выбраны.

Детали

Это использует rsync --dry-run создавать список файлов, которые были бы переданы (это измененные файлы). Это затем использует комбинацию du и ls получить размеры файла и mtime. Это затем сортирует файлы по mtime и затем циклам по ним, пока общий размер не превышает порог. Наконец, это называет rsync снова только с файлами, которые являются последний раз измененным и общим размером под порогом.

Сценарий немного ужасен, но он работает. Одно большое ограничение - то, что это должно быть выполнено на машине, содержащей rsync от каталога. Это может быть изменено для использования ssh для использования удаленного от каталога, но что excersize оставляют читателю.

Наконец, rsync опции трудно кодируются в сценарий, но это - легкое изменение, если Вы хотите указать их на командной строке. Кроме того, математика для вычисления размера сделана в байтах. Это может быть изменено на килограмм/мега/гигабайты путем изменения вызова к du и сокращения порога тем же фактором.

Использование

./rsyncrecent.sh rsync-from-directory rsync-to-directory

где rsync-from-directory локальный каталог и rsync-to-directory любой локальный или удаленный каталог. Опции по умолчанию являются hardcoded как -avz и порог по умолчанию является hardcoded как 10GiB.

Сценарий

#!/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
6
27.01.2020, 20:12
  • 1
    Работает отлично, Одно время, оно не работает, - когда существует файл, больше, чем 10 ГБ, поскольку новый файл –  exussum 05.12.2013, 23:16
  • 2
    Если Вы всегда хотите, чтобы первый файл передал независимо от порога в заключительном цикле в if (( "$size" > "$THRESHOLD" )) условное выражение добавляет проверку (прежде чем break) для i==0 и если так, echo $f >> /tmp/rsyncfilelist. –  casey 06.12.2013, 01:04

Я использовал бы rsync "-пробный прогон" (или "-n") для получения списка более новых файлов. Затем я использовал бы другой rsync с опцией "-файлами - от =-" для отправки файлов. Промежуточный существует "ужасный" жемчуг.
Что-то вроде этого:

#!/usr/bin/perl

$source="/somedir";
$target="host:/remotedir";
$maxsize=10*1024**3; # 10GB 

open (RSOUT,"|rsync -av --files-from=- $source $target");
open (RSIN, "rsync -avn $source $target |");
while (<RSIN>)
{
        chomp;
        last if (/^$/);
        if (-f "$_")
        {
                next if ($size + -s "$_" > $maxsize);
                $size += -s "$_";
                printf RSOUT "%s\n", $_;
        }
}

Обратите внимание, что я не протестировал больше чем с 10 ГБ, возможно, жемчуг переполнится в некотором пределе; для решения этого, вместо того, чтобы считать байты используют Кбайты:

$maxsize=10*1024**2; # 10M of Kbytes
...
     $size +=( -s "$_")/1024;

Править: Я отметил, что это первое решение не отсортирует файл по mtime, вот больше полного решения (подобный сценарию удара, который был отправлен другим человеком).

#!/usr/bin/perl
use File::stat;

$source="/somedir/";
$target="host:/remotedir";
$maxsize=10 * 1024**3; # 10GB  

open (RSOUT,"|rsync -av --files-from=- $source $target");
open (RSIN, "rsync -avn $source $target |");
while (<RSIN>)
{
    chomp;
    last if (/^$/);
    if (-f "$_")
    {
            my $fileattr;
            my $stat=stat($_);
            $fileattr->{name}=$_;
            $fileattr->{size}=$stat->size;
            $hash{sprintf ("%s %s\n", $stat->mtime, $_)}=$fileattr;
    }

}

foreach $key (reverse sort keys %hash)
{
    next if ( ($size + $hash{$key}->{size}) > $maxsize);
    $size += $hash{$key}->{size};
    print RSOUT $hash{$key}->{name}, "\n";
}
1
27.01.2020, 20:12

Можно проанализировать отсортированный вывод du. Утилиты Assuming GNU:

du -0ak | sort -z -k1n | awk -v 'RS=\0' -v 'ORS=\0' '
    (size += $1) > 10*1024*1024 {quit}
    {print substr($0, index(s, "\t")+1)}
' | xargs -0 cp -t destination

POSIXly, предполагая, что никакое имя файла не содержит символ новой строки:

du -ak | sort -k1n | awk '
    (size += $1) > 10*1024*1024 {quit}
    {print substr($0, index(s, "\t")+1)}
' | while IFS= read -r filename; do cp -- "$filename" /path/to/destination

Отметьте это du подкаталоги пересечений. Чтобы избежать что, сказать du на какие файлы Вы хотите воздействовать. В более общем плане можно использовать find отфильтровать файлы.

find . -type f ! -name excluded-file -exec du -ak {} + |
sort -k1n | awk '
    (size += $1) > 10*1024*1024 {quit}
    {print substr($0, index(s, "\t")+1)}
' | while IFS= read -r filename; do cp -- "$filename" /path/to/destination
0
27.01.2020, 20:12
  • 1
    является там способом добавить rsync как функции? это будет выполнено несколько раз, но этот сценарий скопирует файлы многократно? –  exussum 23.10.2013, 22:21
  • 2
    @user1281385 можно звонить rsync вместо cp. –  Gilles 'SO- stop being evil' 24.10.2013, 01:52
  • 3
    справки функция rysnc состояла бы в том, чтобы удалить старые, когда выполнено многократно для не не передачи файла, если уже существует –  exussum 28.11.2013, 19:12

Теги

Похожие вопросы