This snippet defines a function chmod which uses symbolic strings to represent the mode (eg u+rwx) like the shell command 'chmod'.
Change file permissions symbolically (linux).
""" module chmodsym.py (linux)
This module defines a function chmod(location, description)
which allows to change a file's permission with a symbolic
description of the mode, similar to the shell command 'chmod'.
Tested with python 2.6 and 3.1.
"""
import os, stat
import functools
import operator
def chmod(location, description):
"""chmod(location, description) --> None
Change the access permissions of file, using a symbolic description
of the mode, similar to the format of the shell command chmod.
The format of description is
* an optional letter in o, g, u, a (no letter means a)
* an operator in +, -, =
* a sequence of letters in r, w, x, or a single letter in o, g, u
Example:
chmod(myfile, "u+x") # make the file executable for it's owner.
chmod(myfile, "o-rwx") # remove all permissions for all users not in the group.
See also the man page of chmod.
"""
if chmod.regex is None:
import re
chmod.regex = re.compile(r"(?P<who>[uoga]?)(?P<op>[+\-=])(?P<value>[ugo]|[rwx]*)")
mo = chmod.regex.match(description)
who, op, value = mo.group("who"), mo.group("op"), mo.group("value")
if not who:
who = "a"
mode = os.stat(location)[stat.ST_MODE]
if value in ("o", "g", "u"):
mask = ors((stat_bit(who, z) for z in "rwx" if (mode & stat_bit(value, z))))
else:
mask = ors((stat_bit(who, z) for z in value))
if op == "=":
mode &= ~ ors((stat_bit(who, z) for z in "rwx"))
mode = (mode & ~mask) if (op == "-") else (mode | mask)
os.chmod(location, mode)
chmod.regex = None
# Helper functions
def stat_bit(who, letter):
if who == "a":
return stat_bit("o", letter) | stat_bit("g", letter) | stat_bit("u", letter)
return getattr(stat, "S_I%s%s" % (letter.upper(), stat_bit.prefix[who]))
stat_bit.prefix = dict(u = "USR", g = "GRP", o = "OTH")
def ors(sequence, initial = 0):
return functools.reduce(operator.__or__, sequence, initial)
# Test code
def test_code():
import subprocess as sp
def touch(location):
sp.Popen("touch %s" % location, shell=True).wait()
def get_mode_by_ls(location):
"""Run ls and return a string like '-r--r--r-' giving the mode."""
popen = sp.Popen(["ls", "-l", location], stdout=sp.PIPE)
sout, serr = popen.communicate()
return sout[:10]
loc = "xxxx.py"
touch(loc)
print(get_mode_by_ls(loc))
for desc in ("g+rx", "a=g", "o-rw", "u=o", "+rwx", "a-wx"):
chmod(loc, desc)
print("%s --> %s" % (desc, get_mode_by_ls(loc)))
if __name__ == "__main__":
test_code()
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.