无法使Python shutil.copytree忽略模式工作

时间:2017-03-27 14:16:49

标签: python linux shutil copytree

我对Python有点新,但没有编码。我试图让copytree工作,但确实如此,但它不适用于ignore_patterns。我认为这是因为我不知道如何将变量文件列表发送到ignore_patterns()函数。我尝试了一个列表和一个字符串。它说列表不会起作用,因为它不是不可变的。我终于意识到,字符串与任何内容都不匹配,因为它本质上是一个CSV列表。那么如何获取ignore_patterns的参数?

我在Linux上使用Python 2.7(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")),它会工作并忽略这些文件。但它不会忽略它们我传入的参数。基本上,我不知道要传递什么数据结构才能使其工作。我已经尝试了格式" file1,file2,file3"的字符串。我已经尝试了一个列表[" 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 个答案:

答案 0 :(得分:0)

(代表OP发布)

我没有意识到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)