Не удается заставить Python shutil.copytree игнорировать шаблон для работы

Я немного новичок в Python, но не кодирование. Я пытаюсь заставить copytree работать, и он работает, но он не будет работать с ignore_patterns, Я думаю, это потому, что я не знаю, как отправить список переменных файлов в ignore_patterns() функция. Я попробовал список и строку. В нем говорится, что список не будет работать, потому что он не является неизменным. Я наконец понял, что строка ничего не соответствует, потому что по сути это список CSV. Так как мне получить параметры для ignore_patterns?

Я использую Python 2.7 в Linux (AWSLinux). Я импортировал все пакеты, так что вот сама функция, которую я написал:

    def copy_user_data(shadow_data):
        user_data = shadow_data.split(EOL)
        files = ['file1','.file12']
        dirs = ['dir1','.dir12']

        for datum in user_data:
            user = datum.split(":")[0]
            user_home = datum.split(":")[5]

            if os.path.exists(user_home):
                ignore_list = []
                for file in os.listdir(user_home):
                    if file not in files and file not in dirs:
                        ignore_list.append(file)
                ignore_string = "'"+"','".join(ignore_list)+"'"
                logger.info("Copying "+user_home)
                logger.info("ignoring:"+ignore_string)
                dest = os.path.join(TRANSPORT_DIRECTORY,user)
                shutil.copytree(user_home,dest,ignore=shutil.ignore_patterns(ignore_string))

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

ПРИМЕЧАНИЕ. При использовании строки сообщения об ошибках отсутствуют. Copytree копирует ВСЕ файлы и каталоги. Если я перечислю, в частности, параметры в ignore_patterns (например, ignore_patterns("useless.txt","report.pdf")), он работает и игнорирует эти файлы. Но он не игнорирует их с параметрами, которые я передаю. По сути, я не знаю, какую структуру данных передать, чтобы заставить это работать. Я пробовал строку в формате "файл1, файл2, файл3". Я пробовал список ["file1","file2"], но я получаю:

    2017-03-27 11:12:01,748 - __main__ - CRITICAL - UNKNOWN ERROR:<type 'exceptions.Exception'>
    Traceback (most recent call last):
      File "./user_migration.py", line 133, in main
        copy_user_data(passwd_data)
      File "./user_migration.py", line 89, in copy_user_data
        shutil.copytree(user_home,dest,ignore=shutil.ignore_patterns(ignore_list))
      File "/usr/lib64/python2.7/shutil.py", line 173, in copytree
        ignored_names = ignore(src, names)
      File "/usr/lib64/python2.7/shutil.py", line 141, in _ignore_patterns
        ignored_names.extend(fnmatch.filter(names, pattern))
      File "/usr/lib64/python2.7/fnmatch.py", line 51, in filter
        re_pat = _cache[pat]
    TypeError: unhashable type: 'list'

Меньшая версия

    import shutil
    import os


    users = ["bob","joe","list"]
    files = ['.bashrc','.bash_profile']
    dirs = ['.ssh','.google_authenticator']

    for user in users:
        user_home = os.path.join("/home",user)
        if os.path.exists(user_home):
            ignore_list = []
            for file in os.listdir(user_home):
                if file not in files and file not in dirs:
                    ignore_list.append(file)
            ignore_string = "'"+"','".join(ignore_list)+"'"
            dest = os.path.join("/var/tmp/move",user)
            shutil.copytree(user_home,dest,ignore=shutil.ignore_patterns(ignore_string))

1 ответ

(Опубликовано от имени ОП).

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

    def copy_user_data(user_data):

        for datum in user_data:
            user = datum.split(":")[0]
            user_home = datum.split(":")[5]
            if os.path.exists(user_home):
                dest = os.path.join(TRANSPORT_DIRECTORY,user)

                shutil.copytree(user_home,dest,ignore=ignore_files)

    def ignore_files(path, names):
        files = ['.bashrc','.bash_profile','.ssh','.google_authenticator']
        ignore_list = []
        for file in os.listdir(path):
            if file not in files:
                ignore_list.append(file)
        return tuple(ignore_list)            
Другие вопросы по тегам