Das Python-Modul os.chmod (Datei, 664) ändert die Berechtigung nicht in rw-rw-r - aber -w - wx ----

110

Kürzlich habe ich das Python-Modul os verwendet. Als ich versuchte, die Berechtigung einer Datei zu ändern, habe ich nicht das erwartete Ergebnis erhalten. Zum Beispiel wollte ich die Berechtigung in rw-rw-r-- ändern,

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

Die Eigentumserlaubnis lautet tatsächlich -w - wx --- (230)

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

Wenn ich jedoch 664 in 0664 im Code ändere, ist das Ergebnis genau das, was ich brauche, z

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

Das Ergebnis ist:

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

Könnte jemand helfen zu erklären, warum diese führende 0 so wichtig ist, um das richtige Ergebnis zu erzielen?

AplusG
quelle
33
Oktal. Oktal. Oktal.
Cole Johnson
6
Ich habe ein Problem für die Python-Dokumentation unter bugs.python.org/issue25377 geöffnet, da dies aus den Dokumenten ersichtlich sein sollte.
Karl Richter

Antworten:

130

Fand dies in einem anderen Forum

Wenn Sie sich fragen, warum diese führende Null wichtig ist, liegt dies daran, dass Berechtigungen als oktale Ganzzahl festgelegt sind und Python jede Ganzzahl mit einer führenden Null automatisch als oktal behandelt. Also würde os.chmod ("Datei", 484) (in Dezimalzahl) das gleiche Ergebnis liefern.

Was Sie tun, ist zu übergeben, 664was in Oktal ist1230

In Ihrem Fall würden Sie brauchen

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

[Update] Hinweis: Für Python 3 haben Sie das Präfix 0o (null oh). Z.B,0o666

RedBaron
quelle
1
Danke, aber ich bin immer noch verwirrt, dass 484 in Dezimalzahl 744 in Oktal bedeutet, was in dem Thread, den Sie im Forum erwähnt haben, Sinn macht. Wenn ich jedoch 644 in Dezimalzahl gebe, geht es in Oktal auf 1204. In welcher Beziehung steht 1204 zu 230 im Oktal?
AplusG
2
@AplusG: das 1wird nicht verworfen! Das ist das Sticky / Setuid / Setgid-Bit und 1 bedeutet sticky. Bei der Verwendung können ls -lSie feststellen, dass Berechtigungen jetzt Tam Ende ein ...
MestreLion
2
einfacher die 0 hinzuzufügen und oktal zu machen :)
radtek
10
Beachten Sie, dass Sie für Python 3 das Präfix 0o (null oh) haben.
Mawg sagt, Monica wieder einzusetzen
1
Ich benutze 0o in Python 2.7.10
Wyrmwood
124

Also für Leute, die eine ähnliche Semantik wollen wie:

$ chmod 755 somefile

Verwenden:

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

Wenn Ihr Python älter als 2.6 ist:

$ python -c "import os; os.chmod('somefile', 0755)"
Dima
quelle
12
Das Python3-Format funktioniert auch in Python 2.7.9. Ich habe frühere Versionen nicht überprüft.
Fred Mitchell
3
Die Python 3-Syntax funktioniert zurück zu Python 2.6 docs.python.org/3/whatsnew/…
Pete
Arbeite für mich tks!
LandiLeite
Sollte wahrscheinlich sein 00755, nur um klar zu machen, wohin die suid / sgid / sticky-Bits gehen, für den Fall, dass ein späterer Entwickler durchkommt und dieses alte Skript verwenden möchte, zum Beispiel sgid mit 2755, kann dann aber nicht herausfinden, warum Die Dauerwellen sind komplett vermasselt. ;)
dannysauer
10

führend 0bedeutet, dass dies eine Oktalkonstante ist, nicht die Dezimalkonstante. und Sie benötigen ein Oktal, um den Dateimodus zu ändern.

Berechtigungen sind eine Bitmaske zum Beispiel rwxrwx---ist 111111000binär, und es ist sehr einfach zu Sammelbits von 3 auf die Oktal zu konvertieren, als berechnen die Dezimaldarstellung.

0644(oktal) ist 0.110.100.100binär (ich habe Punkte zur besseren Lesbarkeit hinzugefügt) oder, wie Sie berechnen können, 420dezimal.

lenik
quelle
5

Verwenden Sie Berechtigungssymbole anstelle von Zahlen

Ihr Problem wäre vermieden worden, wenn Sie die semantisch benannten Berechtigungssymbole anstelle von rohen magischen Zahlen verwendet hätten, z. B 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
)

Dies ist unter https://docs.python.org/3/library/os.html#os.chmod dokumentiert. Die Namen stimmen mit den unter dokumentierten POSIX C-API- Werten überein man 2 stat.

Ein weiterer Vorteil ist die größere Portabilität, wie in den Dokumenten erwähnt:

Hinweis: Obwohl Windows unterstützt chmod(), können Sie damit nur das schreibgeschützte Flag der Datei setzen (über die Konstanten stat.S_IWRITEund stat.S_IREADoder einen entsprechenden ganzzahligen Wert). Alle anderen Bits werden ignoriert.

chmod +xwird demonstriert unter: Wie macht man ein einfaches "chmod + x" aus Python heraus?

Getestet in Ubuntu 16.04, Python 3.5.2.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
1
Dies ist die richtige Art, mit dem Problem umzugehen.
Carthurs
Ich weiß das auf Python-Art, aber es könnte kaum hässlicher sein :)
Tomasz Swider
2

Wenn Sie die gewünschten Berechtigungen für die Zeichenfolge gespeichert haben, tun Sie dies

s = '660'
os.chmod(file_path, int(s, base=8))
mc.dev
quelle
0

Die Verwendung der stat. * Bit-Masken scheint mir die portabelste und expliziteste Möglichkeit zu sein, dies zu tun. Andererseits vergesse ich oft, wie ich damit am besten umgehen kann. Hier ist ein Beispiel, wie Sie die Berechtigungen "Gruppe" und "Andere" ausblenden und die Berechtigungen "Eigentümer" unberührt lassen. Die Verwendung von Bitmasken und Subtraktion ist ein nützliches Muster.

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)
Jason Drew
quelle