Подтвердить что ты не робот

Изменение разрешения на файл в Python

Я пытаюсь изменить разрешение доступа к файлу:

os.chmod(path, mode)

Я хочу сделать его доступным только для чтения:

os.chmod(path, 0444)

Есть ли другой способ сделать файл доступным только для чтения?

4b9b3361

Ответ 1

os.chmod(path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)

stat

В аргументе 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.

Ответ 2

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'])

Ответ 3

Все текущие ответы сжимают права на запись: они делают файл доступным для чтения, но не исполняемым. Конечно, это связано с тем, что начальный вопрос задавал разрешения 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).

Последний шаг - получить текущие разрешения на файл и фактически выполнить побитовое и операцию.

Ответ 4

Просто включите целочисленные разрешения в восьмеричном виде (работает как для python 2, так и для python3):

os.chmod(path, 0o444)

Ответ 5

Не нужно помнить флаги. Помните, что вы всегда можете сделать:

subprocess.call(["chmod", "a-w", "file/path])

Не переносимо, но легко написать и запомнить:

  • u - пользователь
  • г - группа
  • o - другое
  • а - все
  • + или - (добавить или удалить разрешение)
  • r - читать
  • w - напиши
  • x - выполнить

Обратитесь к man chmod за дополнительными опциями и более подробным объяснением.

Ответ 6

К вашему сведению, здесь есть функция для преобразования строки разрешений с 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).