Как вы делаете простой "chmod + x" изнутри python?

Я хочу создать файл из исполняемого файла python script.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

он появляется os.chmod не "добавляет" разрешения, как делает unix chmod. Когда последняя строка прокомментирована, файл имеет filemode -rw-r--r--, при этом он не закомментирован, режим файла - ---x------. Как я могу добавить флаг u+x, сохранив остальную часть режимов?

Ответ 1

Используйте os.stat() для получения текущих разрешений, используйте | to или биты вместе и используйте os.chmod() для установки обновленных разрешений.

Пример:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)

Ответ 2

Для инструментов, которые генерируют исполняемые файлы (например, скрипты), может оказаться полезным следующий код:

def make_executable(path):
    mode = os.stat(path).st_mode
    mode |= (mode & 0o444) >> 2    # copy R bits to X
    os.chmod(path, mode)

Это делает (более или менее) отношение к umask, которое действовало при создании файла: Исполняемый файл установлен только для тех, кто может читать.

Использование:

path = 'foo.sh'
with open(path, 'w') as f:           # umask in effect when file is created
    f.write('#!/bin/sh\n')
    f.write('echo "hello world"\n')

make_executable(path)

Ответ 3

Если вы знаете, какие разрешения вам нужны, то следующий пример может помочь вам в этом.

Python 2:

os.chmod("/somedir/somefile", 0775)

Python 3:

os.chmod("/somedir/somefile", 0o775)

Совместим с любым (восьмеричное преобразование):

os.chmod("/somedir/somefile", 509)

ссылочные примеры разрешений

Ответ 4

Вы также можете сделать это

>>> import os
>>> st = os.stat("hello.txt")

Текущий список файлов

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt

Теперь сделайте это.

>>> os.chmod("hello.txt", st.st_mode | 0o111)

и вы увидите это в терминале.

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt

Вы можете поразрядно или с 0o111 сделать все исполняемые файлы, 0o222, чтобы сделать все доступными для записи, и 0o444 сделать все доступным для чтения.

Ответ 5

Уважайте umask как chmod +x

man chmod говорит, что если augo не указан как в:

chmod +x mypath

то используется, но с a umask:

Комбинация букв ugoa определяет, какие права доступа пользователей к файлу будут изменены: пользователь, которому он принадлежит (u), другие пользователи в файловой группе (g), другие пользователи, не входящие в файловую группу (o), или все пользователи (а). Если ничего из этого не дано, эффект будет таким, как если бы (а) был задан, но биты, установленные в маске, не затрагиваются.

Вот версия, которая точно имитирует это поведение:

#!/usr/bin/env python3

import os
import stat

def get_umask():
    umask = os.umask(0)
    os.umask(umask)
    return umask

def chmod_plus_x(path):
    os.chmod(
        path,
        os.stat(path).st_mode |
        (
            (
                stat.S_IXUSR |
                stat.S_IXGRP |
                stat.S_IXOTH
            )
            & ~get_umask()
        )
    )

chmod_plus_x('.gitignore')

Смотрите также: Как я могу получить права доступа к файлам по умолчанию в Python?

Протестировано в Ubuntu 16.04, Python 3.5.2.

Ответ 6

В python3:

import os
os.chmod("somefile", 0o664)

Не забудьте добавить префикс 0o поскольку разрешения задаются как восьмеричное целое число, а Python автоматически обрабатывает любое целое число с начальным нулем как восьмеричное. В противном случае вы os.chmod("somefile", 1230) передаете os.chmod("somefile", 1230), который является восьмеричным 664.

Ответ 7

Если вы используете Python 3. 4+, вы можете использовать стандартную библиотеку удобный pathlib.

Его класс Path имеет встроенные методы chmod и stat.

from pathlib import Path


f = Path("/path/to/file.txt")
f.chmod(f.stat().st_mode | stat.S_IEXEC)