Python内から単純な「chmod + x」をどのように実行しますか?


119

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

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

表示されos.chmod、UNIXが道「追加」権限はありませんchmodんが。最後の行がコメントアウトされている場合、ファイルにはfilemodeがあり-rw-r--r--、コメントアウトされていない場合、ファイルモードは---x------です。u+x残りのモードをそのままにしてフラグを追加するにはどうすればよいですか?

回答:


197

使用os.stat()現在のアクセス権、使用取得するために|、一緒にまたはビットを、および使用はos.chmod()、更新権限を設定します。

例:

import os
import stat

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

2
これは、ユーザーが実行できるようにするだけです。ポスターは、「chmod + x」を全面的に(ユーザー、グループ、世界)実行できるようにすることを求めていました
eric.frederich

35
次のコマンドを使用して、全員が実行できるようにします... stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH。注:この値は8進数の0111と同じなので、st.st_mode | 0111
eric.frederich

1
以下の私の答えは、コンパイラから言われているように、RビットをXにコピーします。
Jonathon Reinhart、2015年

私はそうしSTAT_OWNER_EXECUTABLE = stat.S_IEXEC、意味不明なものではなく、人間が読めるローカル定数を使用します。
ThorSummoner

これは、もう少し読みやすいかもしれない非Pythonicの答えです:subprocess.check_call(['chmod', '+x', 'somefile'])そして、のような操作をより簡単に実行しましょうa+rx
Trevor Boyd Smith

20

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

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)

2
8進数リテラルはPython 3で変更されました。代わりにを0444使用します0o444。または、両方をサポートしたい場合は、と書いてください292
Kevin

1
それは@Kevin のように見える新しい構文は、Python 2.6でサポートされているので、それを使用するのが妥当と思われます。(互換性の参照点として、CentOS 6にはPython 2.6が付属しています)。
Jonathon Reinhart 2015年

2
Python 3で従来の8進リテラルが削除されたことに気付きませんでした。それでありがとう。
Jonathon Reinhart、2015年

12

必要なアクセス許可がわかっている場合は、次の例を参考にしてください。

Python 2:

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

Python 3:

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

いずれかと互換性があります(8進変換):

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

参照権限の例


4
これはos.chmod( "/ somedir / somefile"、0o775)である必要があります
ang mo

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を使用してすべてを読み取り可能にすることができます。


2

尊重するumaskようにchmod +x

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でテスト済み。


1

python3の場合:

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

0o許可は8進整数として設定されるため、接頭辞を追加することを忘れないでください。Pythonは、先頭にゼロがある整数を8進として自動的に扱います。それ以外の場合は、os.chmod("somefile", 1230)実際に渡されます664。これはの8進数です。


1
これはアクセス許可を絶対値に設定しますが、chmod +既存のアクセス許可に新しいアクセス許可を追加する必要があるOPからの要求には応じません。
Ciro Santilli郝海东冠状病六四事件法轮功

0

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.