web-dev-qa-db-ja.com

Python内から簡単な「chmod + x」を実行するにはどうすればよいですか?

実行可能なpythonスクリプト内からファイルを作成したい。

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

os.chmodは、unix chmodのようにパーミッションを '追加'しません。最後の行をコメントアウトすると、ファイルのファイルモードは-rw-r--r--になり、コメントアウトしないと、ファイルモードは---x------になります。残りのモードをそのままにして、u+xフラグを追加するにはどうすればよいですか?

100
priestc

os.stat()を使用して現在の許可を取得し、|を使用してビットを一緒に使用し、os.chmod()を使用して更新された許可を設定します。

例:

import os
import stat

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

実行可能ファイル(スクリプトなど)を生成するツールの場合、次のコードが役立つ場合があります。

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)
16

必要なアクセス許可がわかっている場合は、次の例がそのアクセス許可を単純にする方法です。

Python 2:

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

Python 3:

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

いずれかとの互換性(8進変換):

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

参照 許可の例

7
zerocog

これもできます

>>> 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ですべてを実行可能にします。

2
ncmathsadist

chmod +xのようなumaskを尊重する

man chmodは、augoが次のように指定されていない場合:

chmod +x mypath

その後、aが使用されますが、umaskとともに:

Ugoaの文字の組み合わせは、ファイルへのアクセスを変更するユーザーを制御します:ファイルを所有するユーザー(u)、ファイルのグループ内の他のユーザー(g)、ファイルのグループ内にない他のユーザー(o)、またはすべてユーザー(a)。これらのいずれも指定されていない場合、(a)が指定された場合と同じ効果がありますが、umaskに設定されているビットは影響を受けません。

以下は、その動作を正確にシミュレートするバージョンです。

#!/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。

Python3の場合:

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

0oプレフィックスを追加することを忘れないでください。許可は8進整数として設定され、Pythonは先行ゼロを持つ整数を8進数として自動的に処理します。そうでなければ、664の8進数であるos.chmod("somefile", 1230)を渡します。

0
funkid

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)
0
cs01