【问题标题】:copy file, keep permissions and owner复制文件,保留权限和所有者
【发布时间】:2013-11-16 05:31:23
【问题描述】:

shutil 的文档告诉我:

即使是更高级的文件复制函数(shutil.copy()、shutil.copy2())也无法复制所有文件元数据。在 POSIX 平台上,这意味着文件所有者和组以及 ACL 都会丢失

如果我需要在 python 中复制文件,如何保留文件所有者和组?

该进程以 root 身份在 linux 上运行。

更新:我们不使用 ACL。我们只需要保留使用 tar 和 rsync 等工具保存的内容。

【问题讨论】:

    标签: python file-permissions


    【解决方案1】:

    您也许可以使用os.stat 来获取this answer 中的guiduid,然后在使用os.chown 应对后重置uidguid

    【讨论】:

    • 您应该阅读shutil 文档。 copy2 获取除所有者/组以外的所有内容。
    • 您可以使用os.stat 获得uidguid
    • @lunixbochs: 使用os.stat读取源文件的uid、gid然后使用os.chown(path, uid, gid)在目标文件上设置它们有什么问题?
    • 为我工作。我刚刚看到 chmod,而不是 chown(那是在您的编辑中吗?)。您应该注意对 root 权限的潜在要求,以将用户/组任意设置为您以外的其他人。
    • @lunixbochs:问题很明确:“进程在 linux 上以 root 身份运行。”
    【解决方案2】:

    我是这样做的:

    import os
    import stat
    import shutil
    
    def copyComplete(source, target):
        # copy content, stat-info (mode too), timestamps...
        shutil.copy2(source, target)
        # copy owner and group
        st = os.stat(source)
        os.chown(target, st.st_uid, st.st_gid)
    

    【讨论】:

    • 这是一个很好的解决方案。谢谢。
    • 干得好。我喜欢这是便携式的。尽管 OP 特别指出 linux 作为操作系统,但我很欣赏一个便携的答案。
    • 为什么不只是os.chown(target, st.st_uid, st.st_gid)
    【解决方案3】:

    您可以使用subprocess 模块:

    from subprocess import Popen
    
    p = Popen(['cp','-p','--preserve',src,dest])
    p.wait()
    

    【讨论】:

    • 是的,这行得通。但我在没有创建子流程的情况下搜索解决方案。
    • 如果你复制很多文件,这会变得很慢。
    【解决方案4】:

    请参阅Keeping fileowner and permissions after copying file in C cp 本身如何做到这一点,然后复制其逻辑。 Python 具有其os 模块中提到的所有系统调用。

    【讨论】:

      【解决方案5】:

      我建议你使用操作系统和子进程模块。这仅适用于 Unix,但它应该可以正常工作。使用 os.fchown 更改文件所有权,并使用 subprocess.Popen() 将 ls -l 传递到变量以读取所有权。对于一个文件,权限读取器如下所示:

      import os
      import subprocess
      
      def readfile(filepath):
          process = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE)
          output = process.communicate()[0]
          output = output.split()
          return (output[0],output[1])  #insert into this tuple the indexing for the words you want from ls -l
      

      对于 uid 设置器(只是 os 函数的包装器):

      def setuid(filepath,uid,gid):
          os.chown(filepath,uid,gid)
      

      【讨论】:

      • 确实如此。特别是因为 os 具有以编程方式列出目录内容的功能。使用它可能更好。
      【解决方案6】:

      作为@Thom Wiggers 的回答

      • os.stat 获取 uid,gid
      • os.chmod 设置 uid,gid

      演示代码:

      import os
      st = os.stat(src_path)
      os.chown(dst_path, st.st_uid, st.st_gid)
      

      检查除外:

      import os
      def copy_owner_group(src, dst):
          try:
              st = os.stat(src)
          except Exception as e:
              print 'stat except:', e
          else:
              try:
                  os.chown(dst, st.st_uid, st.st_gid)
              except Exception as e:
                  print 'chmod except:', e
      

      【讨论】:

      • 我只是问自己“为什么我需要为此编写代码?为什么没有库可以处理这个?”
      猜你喜欢
      • 2011-07-26
      • 2012-04-17
      • 2013-10-08
      • 2017-04-24
      • 1970-01-01
      • 2018-02-27
      • 2022-01-20
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多