以递归方式将所有者和组设置为目录中的文件的“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)
这似乎适用于设置目录,但在应用于文件时失败。我怀疑文件没有得到整个路径,因此chown失败,因为它无法找到文件。错误是:
'OSError:[Errno 2]没有这样的文件或目录:'foo.html'
我在这里俯瞰什么?
答案 0 :(得分:40)
dirs
和files
列表都始终相对于root
- 即,它们是文件/文件夹的basename()
,即它们没有其中/
(或Windows上的\
)。如果您希望代码能够进行无限级别的递归,则需要将dirs /文件加入root
以获取其完整路径:
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)
我很惊讶shutil
模块没有此功能。
答案 1 :(得分: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)
随意替换aaa
和bb
答案 2 :(得分:4)
尝试os.path.join(root,momo)
,它将为您提供完整的路径
答案 3 :(得分:2)
这是我编写的一个函数,它使用glob来递归列出文件并更改其权限。
import os
import glob
def recursive_file_permissions(path,mode,uid=-1,gid=-1):
'''
Recursively updates file permissions on a given path.
UID and GID default to -1, and mode is required
'''
for item in glob.glob(path+'/*'):
if os.path.isdir(item):
recursive_file_permissions(os.path.join(path,item),mode,uid,gid)
else:
try:
os.chown(os.path.join(path,item),uid,gid)
os.chmod(os.path.join(path,item),mode)
except:
print('File permissions on {0} not updated due to error.'.format(os.path.join(path,item)))
它并不完美,但让我在需要的地方
答案 4 :(得分:2)
接受的答案会错过顶级文件。这实际上是与chown -R
等效的。
import os
path = "/tmp/foo"
os.chown(path, 502, 20)
for dirpath, dirnames, filenames in os.walk(path):
for dname in dirnames:
os.chown(os.path.join(dirpath, dname), 502, 20)
for fname in filenames:
os.chown(os.path.join(dirpath, fname), 502, 20)
答案 5 :(得分:2)
正如上面正确指出的,接受的答案会丢失顶级文件和目录。其他答案使用os.walk
,然后遍历dirnames
和filenames
。但是,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)
答案 6 :(得分:1)
也不要忘记for f in files
循环。同样,请记住os.path.join(root, f)
以获得完整路径。
答案 7 :(得分:0)
我可以将'chown -R'命令传递给shell
这是最简单的方法,并且会在问题中有所遗漏,因此为了清楚起见,如果您不关心Windows,则可以在一行中完成此操作:
os.system('chown -R 502 /tmp/foo')
答案 8 :(得分:0)
"""
Requires python 3
Accepts name or id
Usage:
chown.py -p /temp/folder -u user -g group -r true
or
chown.py -p /temp/folder -u uid -g gid -r 1
user, group, and recursive are optional
But must supply at least one of user or group
Example: sudo chown.py -p /temp/filename -u some_user
"""
import argparse, os, sys
from shutil import chown
user = group = recursive = ''
parser=argparse.ArgumentParser()
parser.add_argument('-p', '--path') # help='file/path'
parser.add_argument('-u', '--user') # , help='user'
parser.add_argument( '-g','--group') # , help='group'
parser.add_argument('-r', '--recursive', help=1) # , help='recursive'
args=parser.parse_args()
path = args.path
if not path:
raise Exception('missing path')
if args.user:
user = args.user
if args.group:
user = args.group
if args.recursive:
recursive = True
if not user and not group:
raise Exception('must supply user, group, or both')
def change_owner(path, user='', group='')
if user and not group:
chown(path, user=user)
elif not user and group:
chown(path, group=group)
else:
chown(path, user, group)
change_owner(path, user, group)
if recursive:
for dirpath, dirnames, filenames in os.walk(path):
for dname in dirnames:
change_owner(os.path.join(dirpath, dname), user, group)
for fname in filenames:
change_owner(os.path.join(dirpath, fname), user, group)
答案 9 :(得分:-2)
使用os.lchown
代替os.chown
自行更改链接和文件。