Pythonモジュールos.chmod(file、664)は権限をrw-rw-r—に変更しませんが、-w--wx ----


111

最近、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

誰かがその先頭の0が正しい結果を得るために非常に重要である理由を説明するのを手伝ってくれませんか?


33
オクタル。オクタル。オクタル。
Cole Johnson

6
ドキュメントからは明らかなはずなので、bugs.python.org / issue25377でpythonドキュメントの問題を開きました。
Karl Richter

回答:


130

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

なぜ先行ゼロが重要なのか疑問に思っているのは、アクセス許可が8進整数として設定されているためであり、Pythonは先行ゼロを持つ整数をすべて8進として自動的に扱います。したがって、os.chmod( "file"、484)(10進数)でも同じ結果が得られます。

あなたがやっていることは6648進法で渡しています1230

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

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

[更新]注意:Python 3の場合、プレフィックスは0o(ゼロ)です。例えば、0o666


1
ありがとう、でも私はまだ混乱しています。10進数で484は8進数で744を意味します。これは、フォーラムであなたが言及したスレッドで意味があります。ただし、10進数で644を指定すると、8進数で1204になります。1204は8進数で230とどのように関連していますか?
AplusG 2013年

2
@AplusG:これ1は破棄されません!これはsticky / setuid / setgidビットであり、1はを意味しstickyます。使用ls -lすると、許可にT最後にが含まれるようになります...
MestreLion

2
0を追加して8進数にするのが簡単:)
radtek '25年

10
Python 3の場合、接頭辞が0o(ゼロ)であることに注意してください。
Mawgは、モニカを2015

1
私はPython 2.7.10で0oを使用しています
Wyrmwood

125

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

$ chmod 755 somefile

使用する:

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

Pythonが2.6より古い場合:

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

12
python3フォーマットは、python 2.7.9でも機能します。以前のバージョンは確認していません。
Fred Mitchell

3
Pythonの3構文は、Pythonに戻って2.6作品docs.python.org/3/whatsnew/...
ピート

私のために働いてくださいTKS!
LandiLeite 2018

おそらく00755、suid / sgid / stickyビットがどこにあるかを明確にするために、後で開発者がこの古いスクリプトを使用したい場合、たとえばsgid withを使用した2755が、その理由を理解できない場合パーマは完全にねじ込まれています。;)
dannysauer

10

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

アクセス許可は、ビットマスクは、例えば、rwxrwx---ある111111000バイナリで、それが小数表現を計算するよりも、進に変換する3によってグループビットに非常に簡単です。

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


5

数字ではなく許可記号を使用する

たとえば、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に記載されており、名前はに記載されているPOSIX C APIの値と同じman 2 statです。

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

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

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

Ubuntu 16.04、Python 3.5.2でテスト済み。


1
これが問題に対処する正しい方法です。
カーサーズ

私はこれをpythonの方法で知っていますが、醜いことはほとんどありません:)
Tomasz

2

文字列に保存する必要な権限がある場合は、次のようにします

s = '660'
os.chmod(file_path, int(s, base=8))

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