Создание очень длинных rsync включений и исключений с Python

Я пытаюсь выполнить резервное копирование всех своих.x папок в Доме для сохранения конфигураций.

С программой я пишу, можно выбрать любые папки, которые Вы хотите включенный или исключенный из резервного копирования, этот список является динамичным.

Я пытаюсь создать что-то вроде этого:

rsync -aP --exclude $Home/.cache/google-chrome/Default/Cache/* --exclude $Home/.cache/google-chrome/Default/Media\ Cache/* --exclude $Home/.wine $HOME/.* /mnt/ext/

Таким образом в вышеупомянутом примере, все копируется во внешний диск за исключением Вина и кэшей Chrome. Я знаю, что могу, создал текстовый файл, и сказать rsync --exclude-from 'textfile' но я не должен считать и переписать текстовый файл.

Мое беспокойство - то, что, поскольку это расширяется, список исключения может стать довольно длинным, так как мой проект в конечном счете запустится включая папки за пределами $HOME, и на долях NFS других систем. Я могу запустить команду и использовать, исключает список в переменной:

exlist = "--exclude $Home/.cache/google-chrome/Default/Cache/* --exclude $Home/.cache/google-chrome/Default/Media\ Cache/* --exclude $Home/.wine" etc etc
subprocess.Popen("rsync -options ",exlist," /source /dest")

Но это собирается вызвать проблемы с чрезвычайно долгими командами оболочки, где я должен буду разбить его в меньшие блоки? Я опередил бы потенциальные будущие проблемы и начал бы писать обработчики, чтобы выполнить это теперь, а не попытаться зафиксировать и исправить его позже.

1
задан 28 June 2016 в 18:56

2 ответа

Я обнаружил, что мои ограничения по размеру не обязательно зависят от длины команды, а скорее от длины аргумента. Команды оболочки могут быть длиной от 100 000 до 200 000 символов. Аргументы, однако, ограничены несколькими сотнями символов в зависимости от системы, как обнаружено с помощью getconf ARG_MAX.

Это приводит меня к возможной проблеме нехватки места, когда я добавил много исключений для папок в мои rsync аргументы.

Чтобы обойти эту проблему, мне нужно программно разделить процесс rsync от одного длинного выполнения на множество меньших.

1136 Чтобы сделать это, нужно «строить как я», пока не достигну предела. Программа попытается создать строку из всех отдельных исключений, каждое из которых находится в списке (массиве). Если предел длины args превышен, он будет повторно анализировать текущий список, чтобы сделать более широкие исключения, уменьшить общее количество и сохранить эти исключенные исключения.

Вот пример списка исключений в процессе его построения:

Этот список называется excludes

(long list items...)  
--exclude $Home/.wine  
--exclude $Home/.cache/somefolders/*   
--exclude $Home/.cache/somefolders/*  
--exclude $Home/.cache/somefolders/*  
--exclude $Home/.cache/somefolders/*   
--exclude $Home/.cache/google-chrome/Default/Cache/*  
--exclude $Home/.cache/google-chrome/Default/Media\ Cache/* 
**LIMIT EXCEEDED**

Теперь у нас превышен предел ARGS. Программа проанализирует этот список в поисках общих папок и создаст второй список, который будет сохранен для следующего выполнения rsync.

После синтаксического анализа excludes перестраивается в список, подобный следующему:

(long list items...)  
--exclude $Home/.wine  
--exclude $Home/.cache/*  

После анализа строки, которые были удалены, были помещены в другой список, назовем его [ 1110] и выглядит следующим образом:

--exclude $Home/.cache/somefolders/*   
--exclude $Home/.cache/somefolders/*  
--exclude $Home/.cache/somefolders/*  
--exclude $Home/.cache/somefolders/*   
--exclude $Home/.cache/google-chrome/Default/Cache/*  
--exclude $Home/.cache/google-chrome/Default/Media\ Cache/*

Таким образом, все повторяющиеся папки удаляются из excludes и помещаются в excludesnext. Когда элементы перемещаются и укороченные широкие папки заменяются на excludes, создается новый список с именем cutlist с этими новыми более короткими папками.

Таким образом, список cutlist включает в себя:

--exclude $Home/.cache/* 

rsync запускается с использованием списка excludes в качестве аргументов.

После окончания rsync список excludes очищается, а список excludesnext копируется в список excludes.

Затем rsync запускается в цикле, используя новый сокращенный список cutlist в качестве источника, и все соответствующие подпапки из excludes используются в качестве исключений.

Конечно, в списке cutlist может быть много элементов, и программа будет перебирать каждый из них. Этот второй прогон rsync выполняется в цикле. Но в этом цикле, когда достигается максимальная длина, список excludes анализируется так же, как и раньше, за исключением того, что новые укороченные папки добавляются в cutlist вместо перехода в excludes. Таким образом, когда цикл проходит через список вырезок, он может расширяться сам по себе, проходя через список. Поскольку элементы списка excludesnext используются, они удаляются.

В конечном итоге это приводит к копированию всех папок и подпапок со всеми включенными исключениями независимо от их количества. Завершение последнего пункта в cutlist означает, что все было выполнено.

Этот метод может заставить rsync запускаться несколько или даже десятки раз, в зависимости от того, сколько у вас исключений, но он никогда не повторяет папки.

Приносим извинения за то, что не публикуем реальный код, но это грязная работа в процессе, и я не чувствую себя комфортно, публикуя свой код еще до того, как смогу выпустить работающий сервис.

1
ответ дан 7 December 2019 в 15:53

я знаю, что могу, создал текстовый файл, и скажите, что rsync - исключают - из 'текстового файла', но я не должен считать и переписать текстовый файл.

Просто сделайте:

with contextlib.closing(tempfile.NamedTemporaryFile()) as exclude_from:
    print(*your_exclude_list, sep="\n", flush=True, file=exclude_from)  # etc
    subprocess.check_call(['rsync', '--exclude-from', exclude_from.name, ...])

... и не волнуются о временном файле. Я ценю тот временный файл, с которым файлы кажутся грязными для контакта, но с библиотекой Python и менеджерами по контексту это может все быть приятно перенесено в пакет с поклоном, таким образом, Вы не должны волноваться об этом.

0
ответ дан 7 December 2019 в 15:53

Другие вопросы по тегам:

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