递归设置文件权限的Python方式是什么?

Geo*_*off 35 python recursion chown

以递归方式将所有者和组设置为目录中的文件的"python方式"是什么?我可以将'chown -R'命令传递给shell,但我觉得我错过了一些明显的东西.

我对此很不满意:


import os  
path = "/tmp/foo"  
for root, dirs, files in os.walk(path):  
  for momo in dirs:  
    os.chown(momo, 502, 20)
Run Code Online (Sandbox Code Playgroud)

这似乎适用于设置目录,但在应用于文件时失败.我怀疑文件没有得到整个路径,因此chown失败,因为它无法找到文件.错误是:

'OSError:[Errno 2]没有这样的文件或目录:'foo.html'

我在这里俯瞰什么?

too*_*php 42

dirsfiles名单都总是相root-也就是说,它们是basename()文件/文件夹,即他们没有/在他们(或\在Windows上).root如果希望代码能够进行无限级别的递归,则需要加入dirs/files来获取它们的整个路径:

import os  
path = "/tmp/foo"  
for root, dirs, files in os.walk(path):  
  for momo in dirs:  
    os.chown(os.path.join(root, momo), 502, 20)
  for momo in files:
    os.chown(os.path.join(root, momo), 502, 20)
Run Code Online (Sandbox Code Playgroud)

我很惊讶shutil模块没有这个功能.

  • @AvindraGoolcharan 很好的收获 - 希望这就是你的想法! (4认同)
  • 这有一个错误,我刚刚在我同事的生产代码中看到了 :-) 指定的顶级目录没有被 chown。我建议进行修复并进行编辑,希望它得到批准。 (3认同)
  • 无需循环遍历“dirs”,因为“os.walk”无论如何都会遍历所有目录。请参阅我的[答案](/sf/answers/4022098531/)。 (3认同)
  • @AvindraGoolcharan 编辑[1](https://stackoverflow.com/review/suggested-edits/13116851),[2](https://stackoverflow.com/review/suggested-edits/11851085),删除[3]( https://stackoverflow.com/review/suggested-edits/11715569)你就出局了。显然,有 9 名评论者认为添加 `os.chown(path, 502, 20)` “偏离了意图”、“应该是一条评论”或“值得做出一个全新的答案”。真的...?一条线?难道所有这些人都不知道 `chmod -R some_dir` 会更改 `some_dir` 及其所有子目录吗?我知道你们都害怕批准代码编辑,但这仍然是愚蠢的 (3认同)
  • 所以我的编辑被拒绝了 - 对使用它并遇到 `/tmp/foo` 没有更改其权限的错误的任何人来说都很好。很好地调节 SO pythonians (2认同)

cri*_*aig 19

我可以将“chown -R”命令传递给 shell

这是最简单的方法,并且有点迷失在这个问题中,所以为了清楚起见,如果您不关心 Windows,您可以在一行中执行此操作:

os.system('chown -R 502 /tmp/foo')
Run Code Online (Sandbox Code Playgroud)

  • 这没有得到足够的信任。Shutil 获得递归功能会很好,但在那之前,为什么还要麻烦.. (2认同)

Chr*_*lis 12

正如上面正确指出的那样,接受的答案遗漏了顶级文件和目录。其他答案使用os.walkthen 循环dirnamesfilenames。但是,无论如何os.walk都会通过dirnames,因此您可以跳过循环dirnames并仅跳过chown当前目录 ( dirpath):

def recursive_chown(path, owner):
    for dirpath, dirnames, filenames in os.walk(path):
        shutil.chown(dirpath, owner)
        for filename in filenames:
            shutil.chown(os.path.join(dirpath, filename), owner)
Run Code Online (Sandbox Code Playgroud)

  • @gerardw我相信os.chown()只接受数字uid和gid,而shutil.chown()将接受名称或数字ID。 (4认同)

Esc*_*alo 6

import os  
path = "/tmp/foo"  
for root, dirs, files in os.walk(path):  
  for momo in dirs:  
    os.chown(momo, 502, 20)
  for file in files:
     fname = os.path.join(root, file)
     os.chown(fname, aaa, bb)
Run Code Online (Sandbox Code Playgroud)

替代aaa,bb随你而去