web-dev-qa-db-ja.com

Python module os.chmod(file、664)は、パーミッションをrw-rw-r--に変更しませんが、-w--wx ----

最近、Python module 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が非常に重要である理由を説明できる人はいますか?

92
AplusG

これを 異なるフォーラム で見つけました

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

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

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

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

[更新]注:Python 3の場合、プレフィックスは0o(ゼロoh)です。 E.G、0o666

107
RedBaron

そのため、次のようなセマンティクスが必要な場合:

$ chmod 755 somefile

python 2:

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

python 3で:

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

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

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

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

8
lenik

数字の代わりに許可記号を使用する

生のマジック番号ではなく名前付きの許可シンボルを使用していた場合、問題は回避されていました。 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。