Я пытаюсь изменить разрешение доступа к файлу:
os.chmod(path, mode)
Я хочу сделать его доступным только для чтения:
os.chmod(path, 0444)
Есть ли другой способ сделать файл доступным только для чтения?
Я пытаюсь изменить разрешение доступа к файлу:
os.chmod(path, mode)
Я хочу сделать его доступным только для чтения:
os.chmod(path, 0444)
Есть ли другой способ сделать файл доступным только для чтения?
os.chmod(path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
В аргументе mode также могут использоваться следующие флаги os.chmod():
stat.S_ISUID
Установить бит UID.
stat.S_ISGID
Идентификатор Set-group-ID. Этот бит имеет несколько специальных применений. Для в каталоге это указывает, что для этой цели будет использоваться семантика BSD directory: файлы, созданные там, наследуют их идентификатор группы из а не от идентификатора эффективной группы процесса создания, и создаваемые там каталоги также получат бит бит S_ISGID. Для файл, у которого нет набора бит выполнения группы (S_IXGRP), бит set-group-ID указывает обязательную блокировку файла/записи (см. также S_ENFMT).
stat.S_ISVTX
Липкий бит. Когда этот бит установлен в каталоге, это означает что файл в этом каталоге может быть переименован или удален только владелец файла, владельцем каталога или привилегированным процесс.
stat.S_IRWXU
Маска для прав владельца файла.
stat.S_IRUSR
У владельца есть разрешение на чтение.
stat.S_IWUSR
У владельца есть разрешение на запись.
stat.S_IXUSR
У владельца есть разрешение на выполнение.
stat.S_IRWXG
Маска для групповых разрешений.
stat.S_IRGRP
У группы есть разрешение на чтение.
stat.S_IWGRP
У группы есть разрешение на запись.
stat.S_IXGRP
У группы есть разрешение на выполнение.
stat.S_IRWXO
Маска для разрешений для других (не в группе).
stat.S_IROTH
У других есть разрешение на чтение.
stat.S_IWOTH
У других есть разрешение на запись.
stat.S_IXOTH
Другие имеют разрешение на выполнение.
stat.S_ENFMT
Принудительное блокирование файла V. Этот флаг является общим с S_ISGID: блокировка файла/записи применяется к файлам, которые не имеют бит выполнения группы (S_IXGRP).
stat.S_IREAD
Синоним Unix V7 для S_IRUSR.
stat.S_IWRITE
Синоним Unix V7 для S_IWUSR.
stat.S_IEXEC
Синоним Unix V7 для S_IXUSR.
os.chmod(path, 0444)
- это команда Python для изменения прав доступа к файлам в Python 2.x. Для комбинированного решения Python 2 и Python 3 измените 0444
на 0o444
.
Вы всегда можете использовать Python для вызова команды chmod с помощью subprocess
. Я думаю, что это будет работать только на Linux.
import subprocess
subprocess.call(['chmod', '0444', 'path'])
Все текущие ответы сжимают права на запись: они делают файл доступным для чтения, но не исполняемым. Конечно, это связано с тем, что начальный вопрос задавал разрешения 444
- но мы можем сделать лучше!
Здесь решение, которое оставляет все отдельные "прочитанные" и "исполняемые" биты нетронутыми. Я написал подробный код, чтобы было легко понять; вы можете сделать его более кратким, если хотите.
import os
import stat
def remove_write_permissions(path):
"""Remove write permissions from this path, while keeping all other permissions intact.
Params:
path: The path whose permissions to alter.
"""
NO_USER_WRITING = ~stat.S_IWUSR
NO_GROUP_WRITING = ~stat.S_IWGRP
NO_OTHER_WRITING = ~stat.S_IWOTH
NO_WRITING = NO_USER_WRITING & NO_GROUP_WRITING & NO_OTHER_WRITING
current_permissions = stat.S_IMODE(os.lstat(path).st_mode)
os.chmod(path, current_permissions & NO_WRITING)
Почему это работает?
Как указал Джон Ла Рой, stat.S_IWUSR
в основном означает "битмаску для прав пользователя на запись". Мы хотим установить соответствующий бит разрешения в 0. Для этого нам нужна точная противоположная битовая маска (то есть одна с 0 в этом месте и 1 везде). Оператор ~
, который переворачивает все биты, дает нам именно это. Если мы применим это к любой переменной с помощью "побитового и" оператора (&
), он будет обнулять соответствующий бит.
Нам также нужно повторить эту логику с "групповыми" и "другими" битами разрешения. Здесь мы сможем сэкономить некоторое время, просто &
, объединяя их все вместе (формируя константу бит NO_WRITING
).
Последний шаг - получить текущие разрешения на файл и фактически выполнить побитовое и операцию.
Просто включите целочисленные разрешения в восьмеричном виде (работает как для python 2, так и для python3):
os.chmod(path, 0o444)
Не нужно помнить флаги. Помните, что вы всегда можете сделать:
subprocess.call(["chmod", "a-w", "file/path])
Не переносимо, но легко написать и запомнить:
Обратитесь к man chmod
за дополнительными опциями и более подробным объяснением.
К вашему сведению, здесь есть функция для преобразования строки разрешений с 9 символами (например, "rwsr-x-wt") в маску, которую можно использовать с os.chmod()
.
def perm2mask(p):
assert len(p) == 9, 'Bad permission length'
assert all(p[k] in 'rw-' for k in [0,1,3,4,6,7]), 'Bad permission format (read-write)'
assert all(p[k] in 'xs-' for k in [2,5]), 'Bad permission format (execute)'
assert p[8] in 'xt', 'Bad permission format (execute other)'
m = 0
if p[0] == 'r': m |= stat.S_IRUSR
if p[1] == 'w': m |= stat.S_IWUSR
if p[2] == 'x': m |= stat.S_IXUSR
if p[2] == 's': m |= stat.S_IXUSR | stat.S_ISUID
if p[3] == 'r': m |= stat.S_IRGRP
if p[4] == 'w': m |= stat.S_IWGRP
if p[5] == 'x': m |= stat.S_IXGRP
if p[5] == 's': m |= stat.S_IXGRP | stat.S_ISGID
if p[6] == 'r': m |= stat.S_IROTH
if p[7] == 'w': m |= stat.S_IWOTH
if p[8] == 'x': m |= stat.S_IXOTH
if p[8] == 't': m |= stat.S_IXOTH | stat.S_ISVTX
return m
Обратите внимание, что установка битов SUID/SGID/SVTX автоматически установит соответствующий бит выполнения. Без этого полученное разрешение будет недействительным (символы ST
).