128

最近、PythonモジュールOSを使用していますが、ファイルのアクセス許可を変更しようとすると、期待した結果が得られませんでした。たとえば、権限をrw-rw-r--に変更するつもりでした。

os.chmod("/tmp/test_file", 664)

所有権の許可は実際には-w--wx---(230)

--w--wx--- 1 ag ag 0 Mar 25 05:45 test_file

ただし、コードで664を0664に変更すると、結果は必要なものになります。たとえば、

os.chmod("/tmp/test_file", 0664)

結果は次のとおりです。

-rw-rw-r-- 1 ag ag 0 Mar 25 05:55 test_file

正しい結果を得るには、先行ゼロが非常に重要である理由を誰かが説明するのを手伝ってもらえますか?

4

7 に答える 7

152

別のフォーラムでこれを見つけました

先行ゼロが重要である理由がわからない場合は、権限が8進数の整数として設定されており、Pythonは先行ゼロの整数を8進数として自動的に処理するためです。したがって、os.chmod( "file"、484)(10進数)でも同じ結果が得られます。

あなたがしていることは664、8進数でどれを渡すかです1230

あなたの場合、あなたは必要になるでしょう

os.chmod("/tmp/test_file", 436)

[更新]Python3の場合、プレフィックスに0o(ゼロoh)が付いていることに注意してください。例えば、0o666

于 2013-03-25T05:01:14.547 に答える
138

したがって、次のようなセマンティクスが必要な人のために:

$ chmod 755 somefile

使用する:

$ python -c "import os; os.chmod('somefile', 0o755)"

Pythonが2.6より古い場合:

$ python -c "import os; os.chmod('somefile', 0755)"
于 2013-07-21T20:50:14.463 に答える
14

stat.S_I*生の8進数の代わりに許可記号()を使用する

生のマジックナンバーではなく、より意味的に名前が付けられた許可記号を使用していれば、問題は回避されたでしょう664

#!/usr/bin/env python3

import os
import stat

os.chmod(
    'myfile',
    stat.S_IRUSR |
    stat.S_IWUSR |
    stat.S_IRGRP |
    stat.S_IWGRP |
    stat.S_IROTH
)

これはhttps://docs.python.org/3/library/os.html#os.chmodに文書化されており、名前はPOSIXCAPIと同じです。POSIXCAPIman 2 statはおよびに存在しman 2 chmodます。

S_IRUSR  (00400)  read by owner
S_IWUSR  (00200)  write by owner
S_IXUSR  (00100)  execute/search by owner
S_IRGRP  (00040)  read by group
S_IWGRP  (00020)  write by group
S_IXGRP  (00010)  execute/search by group
S_IROTH  (00004)  read by others
S_IWOTH  (00002)  write by others
S_IXOTH  (00001)  execute/search by others

もう1つの利点は、ドキュメントに記載されているように、移植性が高いことです。

注:Windowsはをサポートしていchmod()ますが、ファイルの読み取り専用フラグを設定できるのは、(stat.S_IWRITEおよびstat.S_IREAD定数または対応する整数値を介して)のみです。他のすべてのビットは無視されます。

chmod +xで示されています:Python内から単純な「chmod + x」をどのように実行しますか?

Ubuntu 16.04、Python3.5.2でテスト済み。

于 2019-04-09T10:45:46.770 に答える
13

先頭0は、これが10進数ではなく、 8進数の定数であることを意味します。ファイルモードを変更するには8進数が必要です。

パーミッションはビットマスクです。たとえば、バイナリでrwxrwx---あり111111000、小数表現を計算するよりも、ビットを3でグループ化して8進数に変換するのは非常に簡単です。

0644(8進数)は0.110.100.1002進数(読みやすくするためにドットを追加)、または計算する420と10進数です。

于 2013-03-25T05:01:30.653 に答える
7

文字列に保存したい権限がある場合は、

s = '660'
os.chmod(file_path, int(s, base=8))
于 2020-02-04T07:54:36.690 に答える
1

@ mc.devの答えがここでの最良の答えでした。私はそれを利用して、以下の関数ラッパーを再利用できるようにしました。共有していただきありがとうございます。

def chmod_digit(file_path, perms):
    """
    Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself.
    Credits: https://stackoverflow.com/a/60052847/1621381
    """
    os.chmod(file_path, int(str(perms), base=8))
于 2021-04-22T02:10:37.517 に答える
0

stat。*ビットマスクを使用することは、これを行うための最も移植性が高く明示的な方法のように思えます。しかしその一方で、私はそれをどのように処理するのが最善かを忘れがちです。したがって、「グループ」および「その他」の権限をマスクして、「所有者」の権限を変更しないままにする例を次に示します。ビットマスクと減算を使用することは有用なパターンです。

import os
import stat
def chmodme(pn):
    """Removes 'group' and 'other' perms. Doesn't touch 'owner' perms."""
    mode = os.stat(pn).st_mode
    mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
    os.chmod(pn, mode)
于 2020-04-08T14:26:53.163 に答える