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

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
tux21b
User
Beiträge: 18
Registriert: Mittwoch 15. Februar 2006, 23:20
Wohnort: Linz.at
Kontaktdaten:

Warum braucht ihr da alle so ein eigenartiges Dict mit allen möglichen Permutationen? Ihr könnt einfach die Bits durchgehen...

Code: Alles auswählen

import os

def symbolic_notation(mode):
    notation = list(reversed('rwxrwxrwx'))
    return ''.join(mode & 2**i and notation[i] or '-' for i in range(8, -1, -1))
    
print symbolic_notation(os.stat('blub').st_mode)
Das ganze sollte auch relativ leicht um Sticky-Bits etc. erweiterbar sein...

Gruß
Christoph
[url]http://www.ubuntuusers.de[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, ich hab es nun mal eingebaut: http://pylucid.net:8080/pylucid/changeset/1389

Das ganze steckt im zusätzlichen django template filter, hier: http://pylucid.net:8080/pylucid/browser ... y?rev=1389

@tux21b: Natürlich ist ein daten dict mit allen Permutationen etwas unschön. Aber ich finde die Variante viel einfach zu lesen als deine. Ich weiß auf den ersten Blick nicht, wie deine Variante arbeitet...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Jens, dein dict ist doch Quatsch, wenn es von 0 bis 7 geht, da gibts so ne Struktur die heißt Listen, genau für sowas.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Jep stimmt! Und noch besser, ein tuple nehmen ;)
http://pylucid.net:8080/pylucid/changeset/1393

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Und nun bitte noch ``result = []`` entfernen. :-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
tux21b
User
Beiträge: 18
Registriert: Mittwoch 15. Februar 2006, 23:20
Wohnort: Linz.at
Kontaktdaten:

jens hat geschrieben:@tux21b: Natürlich ist ein daten dict mit allen Permutationen etwas unschön. Aber ich finde die Variante viel einfach zu lesen als deine. Ich weiß auf den ersten Blick nicht, wie deine Variante arbeitet...
Liegt wohl daran, dass ich das ganze sehr kurz gefasst habe, aber vom Algorithmus her finde ich die Variante doch um einiges verständlicher.

Kurz gesagt, du gehst alle Bits der Reihe nach durch, schaust nach ob es gesetzt ist und wenn ja, zeigst du das symbol dafür an und ansonsten einen '-'.
[url]http://www.ubuntuusers.de[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

OK, versuchen wir das mal auseinander zu nehmen (Fragen, siehe Kommentar):

Code: Alles auswählen

import os

CHMOD_TRANS_DATA = ("x","w","r")*3

def symbolic_notation(mode):
    result = []
    for i in xrange(8, -1, -1):
        # Wie kann man "m" besser benennen???
        m = mode & 2**i 

        # Was passiert hier genau?
        symbols = m and CHMOD_TRANS_DATA[i] or '-'

        result.append(symbols)

    return ''.join(result)

test_data = (0100000, 0100123, 0100456, 0100765)
for mode in test_data:

    print "%o -> %s" % (mode, symbolic_notation(mode))
    print "="*80
EDIT: Hab mal eine Wiki Seite angelegt: [wiki]755 -> rwxr-xr-x[/wiki](Doller Name, oder?)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Oder so:

Code: Alles auswählen

>>> ''.join(0755 & 0400 >> i and x or '-' for i, x in enumerate('rwxrwxrwx'))
'rwxr-xr-x'
MfG
HWK
tux21b
User
Beiträge: 18
Registriert: Mittwoch 15. Februar 2006, 23:20
Wohnort: Linz.at
Kontaktdaten:

HWK hat geschrieben:Oder so:

Code: Alles auswählen

>>> ''.join(0755 & 0400 >> i and x or '-' for i, x in enumerate('rwxrwxrwx'))
'rwxr-xr-x'
MfG
HWK
Das gefällt mir. enumerate ist verständlicher, und das ganze ist nocheinmal kürzer :D
[url]http://www.ubuntuusers.de[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab das mal auf der Wiki Seite übernommen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab mit http://wiki.python.de/755%20-%3E%20rwxr-xr-x nochmal angesehen.

Was soll ich sagen, alle drei Beispiele funktionieren nicht wirklich:

Code: Alles auswählen

def symbolic_notation1(mode):
    """
    >>> symbolic_notation1(644)
    u'rw-r--r--'
    >>> symbolic_notation1(40755)
    u'rwxr-xr-x'
    >>> symbolic_notation1("777")
    u'rwxrwxrwx'
    """
    return ''.join(
        mode & 0400 >> i and x or '-' for i, x in enumerate('rwxrwxrwx')
    )

def symbolic_notation2(mode):
    """
    >>> symbolic_notation2(644)
    u'rw-r--r--'
    >>> symbolic_notation2(40755)
    u'rwxr-xr-x'
    >>> symbolic_notation2("777")
    u'rwxrwxrwx'
    """
    result = []
    for i, x in enumerate('rwxrwxrwx'):
        m = mode & 0400 >> i
        symbol = m and x or '-'
        result.append(symbol)

    return ''.join(result)


CHMOD_TRANS_DATA = (
    u"---", u"--x", u"-w-", u"-wx", u"r--", u"r-x", u"rw-", u"rwx",
)
def symbolic_notation3(mode):
    """
    >>> symbolic_notation3(644)
    u'rw-r--r--'
    >>> symbolic_notation3(40755)
    u'rwxr-xr-x'
    >>> symbolic_notation3("777")
    u'rwxrwxrwx'
    """
    mode = mode & 0777 # strip "meta info"
    mode_string = u"%o" % mode

    return u''.join(CHMOD_TRANS_DATA[int(num)] for num in mode_string)

if __name__ == "__main__":
    import doctest
    print doctest.testmod(verbose=False)
Ausgaben:

Code: Alles auswählen

...
3 items had failures:
   3 of   3 in __main__.symbolic_notation1
   3 of   3 in __main__.symbolic_notation2
   3 of   3 in __main__.symbolic_notation3
***Test Failed*** 9 failures.
TestResults(failed=9, attempted=9)
:shock:


Meine Aktuelle Lösung, die auch funktioniert:

Code: Alles auswählen

CHMOD_TRANS_DATA = (
    u"---", u"--x", u"-w-", u"-wx", u"r--", u"r-x", u"rw-", u"rwx"
)
def chmod_symbol(octal_value):
    """
    Transform a os.stat().st_octal_value octal value to a symbolic string.
    ignores meta infromation like SUID, SGID or the Sticky-Bit.
    e.g. 40755 -> rwxr-xr-x
    >>> chmod_symbol(644)
    u'rw-r--r--'
    >>> chmod_symbol(40755)
    u'rwxr-xr-x'
    >>> chmod_symbol("777")
    u'rwxrwxrwx'
    """
    octal_value_string = str(octal_value)[-3:] # strip "meta info"
    return u''.join(CHMOD_TRANS_DATA[int(num)] for num in octal_value_string)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Warum nicht einfach so?

Code: Alles auswählen

def chmod_sym(val):
    def tripple(v):
        return "-r"[bool(v & 4)] + "-w"[bool(v & 2)] + "-x"[bool(v & 1)]
    return tripple(val / 64) + tripple(val / 8) + tripple(val)
Wobei das mit dem bool zugegebenermaßen ein bisschen trickreich ist - aber kürzer als ein if/else ;)
Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Tut's nicht (btw. Code ist im Forum Falsch, wegen: http://www.python-forum.de/viewtopic.php?f=10&t=22855 ):

Code: Alles auswählen

def chmod_sym(val):
    """
    >>> chmod_sym(644)
    u'rw-r--r--'
    >>> chmod_sym(40755)
    u'rwxr-xr-x'
    >>> chmod_sym("777")
    u'rwxrwxrwx'
    """
    val = int(val)
    def tripple(v):
        return "-r"[bool(v & 4)] + "-w"[bool(v & 2)] + "-x"[bool(v & 1)]
    return tripple(val / 64) + tripple(val / 8) + tripple(val)

if __name__ == "__main__":
    import doctest
    print doctest.testmod(verbose=False)

Code: Alles auswählen

**********************************************************************
File "test.py", line 4, in __main__.chmod_sym
Failed example:
    chmod_sym(644)
Expected:
    u'rw-r--r--'
Got:
    '-w----r--'
**********************************************************************
File "test.py", line 6, in __main__.chmod_sym
Failed example:
    chmod_sym(40755)
Expected:
    u'rwxr-xr-x'
Got:
    'r--rw--wx'
**********************************************************************
File "test.py", line 8, in __main__.chmod_sym
Failed example:
    chmod_sym("777")
Expected:
    u'rwxrwxrwx'
Got:
    'r----x--x'
**********************************************************************
1 items had failures:
   3 of   3 in __main__.chmod_sym
***Test Failed*** 3 failures.
TestResults(failed=3, attempted=3)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jens hat geschrieben:Tut's nicht
Der Code von sma hätte die Zahlen gerne explizit als Oktalzahl angegeben. Damit schlägt zwangsläufig jeder der bestehenden Tests fehl.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Tut sehr wohl, weil 644 eben nicht 0644 ist. Wie "/me" schon schrieb, ich erwarte natürlich die korrekte Zahl, also beispielsweise 420 oder 0x1a4 oder eben 0644. Das sind ja nur drei verschiedene Repräsentationen für die Zahl, die hinter rw-r--r-- steht.

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

sma hat geschrieben:also beispielsweise 420 oder 0x1a4 oder eben 0644. Das sind ja nur drei verschiedene Repräsentationen für die Zahl
Hm. Die kann man allerdings nicht wirklich gut unterscheiden, oder? Also das man die Funktion mit allem füttern kann...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Man kann zumindest eine Bereichsprüfung machen, wenn die Zahl größer 0777 ist, dann ist sie mit ziemlicher Sicherheit falsch.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Jenseits von 511 sind noch weitere Flags. Meiner Funktion ist das aber egal, die werden einfach ignoriert.

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

jens hat geschrieben:Hab mit http://wiki.python.de/755%20-%3E%20rwxr-xr-x nochmal angesehen.

Was soll ich sagen, alle drei Beispiele funktionieren nicht wirklich:
OK, mein Fehler...

Es geht ja eigentlich um die Umwandlung von os.stat().st_mode und dabei bekommt man halt die Zahl in Octal...

EDIT: Hab das mal im Wiki versucht zu erklären: http://wiki.python.de/755%20-%3E%20rwxr ... 2=7&rev1=6

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten