Seite 1 von 3

Dateirechte ermitteln & 755 -> rwxr-xr-x ???

Verfasst: Montag 11. Februar 2008, 11:15
von jens
Gibt es eigentlich eine einfache Möglichkeit zu ermitteln, ob man die richtigen Rechte besitzt um Dateioperation XY machen zu können?
Oder müßte ich das zu Fuss per os.stat() herrausfinden?

Verfasst: Montag 11. Februar 2008, 11:22
von CM
Hoi Jens,

Hilft Dir os.access weiter? Oder möchtest Du doch was Anderes erfahren?

Gruß,
Christian

Verfasst: Montag 11. Februar 2008, 11:42
von jens
Ja, das sieht schon mal nicht schlecht aus, dank dir ;)

Verfasst: Montag 11. Februar 2008, 12:45
von jens
Existiert eigentlich irgendwo eine Routine um os.stat()[stat.ST_MODE] von Oktalnotation auf Symbolische Notation umzuformen ?

Verfasst: Montag 11. Februar 2008, 14:56
von jens
Also ich hab nun lange rumgesucht, aber nichts in der Richtung gefunden :(
Kennt jemand eine Routine dafür?

Verfasst: Montag 11. Februar 2008, 17:54
von CM
Ich nicht. Wenn niemand eine Alternative weiß: Selber rechnen oder os.access mehrmals aufrufen, um die vollständige Info zu erhalten.

Gruß,
Christian

Verfasst: Montag 11. Februar 2008, 19:02
von jens
Also ich kann mir einfach nicht vorstellen, das es nicht schon irgendjemand mal implementiert hat... Aber nach nochmaligem suchen hab ich immer noch keinen Ansatz gefunden :(

Verfasst: Montag 11. Februar 2008, 19:40
von gerold
Was ist die "Symbolische Notation"?

Verfasst: Montag 11. Februar 2008, 19:43
von jens

Verfasst: Montag 11. Februar 2008, 19:44
von CM
Z. B. -rwxr-xr-x für 755.

edit: zu langsam

Verfasst: Montag 11. Februar 2008, 20:59
von Leonidas
Halbgare rekursive Lösung (die nicht mit Sticky-Bit etc- funktioniert):

Code: Alles auswählen

def o2s_recurse(octal):
    values = ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']
    last_bit = octal % 8
    symbolic = []
    if octal / 8 != 0:
        symbolic.extend(o2s_recurse(octal / 8))
    symbolic.append(values[last_bit])
    return symbolic

def o2s(octal):
    value = ''.join(o2s_recurse(octal))
    fill = 9 - len(value)
    return fill * '-' + value
    
print o2s(0764)
print o2s(0000)
Wenn man die einzelnen Stellen etwa 7 in 1, 2, und 4 zerlegen könnte, wäre das alles einfacher und schöner zu implementieren.

Verfasst: Montag 11. Februar 2008, 21:17
von rafael
Die einfache Methode: http://paste.pocoo.org/show/27137/
Leonidas hat geschrieben: Wenn man die einzelnen Stellen etwa 7 in 1, 2, und 4 zerlegen könnte, wäre das alles einfacher und schöner zu implementieren.
Jap, hab ich auch schon dran rumgeknobelt.

Verfasst: Montag 11. Februar 2008, 21:43
von birkenfeld

Code: Alles auswählen

print ''.join(d if c=='1' else '-' for (c,d) in zip(bin(octal), 'rwxrwxrwx'))
bin() halt geeignet implementieren oder Py3k benutzen :D

Verfasst: Montag 11. Februar 2008, 22:03
von jens
rafael hat geschrieben:Die einfache Methode: http://paste.pocoo.org/show/27137/
Das sieht gut aus, aber warum kein dict nutzten? Werde ich morgen mal umschreiben...

Verfasst: Montag 11. Februar 2008, 23:26
von Leonidas
jens hat geschrieben:
rafael hat geschrieben:Die einfache Methode: http://paste.pocoo.org/show/27137/
Das sieht gut aus, aber warum kein dict nutzten?
Und noch dazu iterativ? Das geht ja mal gar nicht :P

rafael, willst du uns mit der Reihenfolge 4, 2, 6, 1, 5, 3, 7 irgendwas mitteilen ;)

Außerdem fehlen uns ja noch so Juwelen wie Set UID, Set GUID und Sticky-Bit (jeweils +4, +2 und +1 dazurechnen). Die Regeln dafür sind Klasse: aus rwx wird mit +s ein rws, aus rw- wird rwS und das gleiche gibts mit dem Sticky-Bit noch mal mit dem Buchstaben T. 8)

Edit: birkenfeld, cool. Das ist mal was nicht-langweiliges :idea:

Verfasst: Dienstag 12. Februar 2008, 09:13
von jens
Also ganz so einfach scheint das ja nicht zu sein :(

Ich hab Rafaels Vearinate mal umgestrickt:

Code: Alles auswählen

def trans_chmod(mod):
    trans_data = {
        "0": "---",
        "1": "--x",
        "2": "-w-",
        "3": "-wx",
        "4": "r--",
        "5": "r-x",
        "6": "rw-",
        "7": "rwx",
    }
    mod_string = "%04d" % mod
    mod_string = mod_string[-3:]

    return ''.join(trans_data[num] for num in mod_string)
Schön ist das nicht, funktioniert aber...

Das Problem ist aber ein ganz anderes: os.stat()[stat.ST_MODE] liefert ein viel umfasserendes octal Schema zurück, als die einfache 3er Geschichte, die der Sourceocode oben abdeckt...

stat liefert z.B. solche Werte: 33188, 16877
Keine Ahnung wie man die behandeln sollte...

In dem zusammenhang hab ich das gefunden:
http://svn.pythonpaste.org/Paste/Script ... ckperms.py

Macht aber genau das falsche... Es konvertiert von Symbolisch in octalzahl...

Verfasst: Dienstag 12. Februar 2008, 09:58
von BlackJack
Es gibt ja mehr als die 9 Statusbits. Sticky- und SUID-Bit zum Beispiel. Wenn Du nur die "rwx"-Bits haben willst, musst Du die Bits über dem 9. ausblenden:

Code: Alles auswählen

In [13]: os.stat('test.py').st_mode
Out[13]: 33252

In [14]: os.stat('test.py').st_mode & 0777
Out[14]: 484

Verfasst: Dienstag 12. Februar 2008, 10:03
von jens
Wäre eine schnelle Lösung und auch erstmal akzeptabel für mich, wobei natürlich alle Informationen schon nett wären...

Das "ausblenden" klappt aber so nicht:
33188 -> 420
16877 -> 493

Code: Alles auswählen

for fn in sorted(os.listdir(".")):
    mode = os.stat(fn).st_mode
    print "%s -> %s" % (mode, mode & 0777)

Verfasst: Dienstag 12. Februar 2008, 10:25
von BlackJack
Was sind denn die Rechte zu den dazugehörigen Dateien? Zum Vergleichen bietet es sich an die Zahl als Oktalzahl dar zu stellen (Formatcode '%o').

Verfasst: Dienstag 12. Februar 2008, 10:29
von jens
Das ist es!

Code: Alles auswählen

def trans_chmod(mod):
    trans_data = {
        "0": "---",
        "1": "--x",
        "2": "-w-",
        "3": "-wx",
        "4": "r--",
        "5": "r-x",
        "6": "rw-",
        "7": "rwx",
    }
    result = []
    mod = mod & 0777 # strip "meta info"
    mod_string = "%o" % mod

    return ''.join(trans_data[num] for num in mod_string)

for fn in sorted(os.listdir(".")):
    #~ print fn
    mode = os.stat(fn).st_mode
    print "%o -> %o" % (mode, mode & 0777)
    print trans_chmod(mode)

    print "="*80
Bsp:
100644 -> 644
rw-r--r--
================================================================================
40755 -> 755
rwxr-xr-x
================================================================================
Das werde ich erstmal nutzten...