Что такое способ Python для рекурсивного задания прав доступа к файлам?
Что такое "способ python", чтобы рекурсивно установить владельца и группу в файлы в каталоге? Я мог бы просто передать команду chown -R в оболочку, но я чувствую, что мне не хватает чего-то очевидного.
Я обманываю с этим:
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 '
Что я здесь не вижу?
Ответы
Ответ 1
Списки dirs
и files
всегда относятся к root
, т.е. они являются basename()
файлов/папок, то есть они не имеют /
в них (или \
на окнах). Вам нужно присоединиться к файлам/файлам 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
не имеет функции для этого.
Ответ 2
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
, как вам угодно
Ответ 3
попробуйте os.path.join(root,momo)
, который даст вам полный путь
Ответ 4
Вот функция, которую я написал, которая использует 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)))
это не идеально, но я получил там, где мне нужно было
Ответ 5
Принятый ответ не попадает в файлы верхнего уровня. Это фактический эквивалент 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)
Ответ 6
Не забудьте также цикл for f in files
. Аналогично, запомните os.path.join(root, f)
, чтобы получить полный путь.
Ответ 7
Как правильно указано выше, принятый ответ пропускает файлы и каталоги верхнего уровня. Другие ответы используют 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)
Ответ 8
Я мог бы просто передать команду 'chown -R' в оболочку
Это самый простой способ, и он немного теряется в вопросе, так что для ясности вы можете сделать это в одну строку, если вам нет дела до Windows:
os.system('chown -R 502 /tmp/foo')
Ответ 9
используйте os.lchown
вместо os.chown
для изменения самих ссылок и файлов.