Entry
How can I get a file's permissions?
Oct 8th, 2006 04:14
James Stroud, unknown unknown, Fredrik Lundh, James Stroud
Problem:
I have been able to get a file's owner and group IDs using the os.stat
function but it doesn't seem to give me the file's permissions.
Solution:
the first member of the stat tuple (ST_MODE) contains the permissions,
as a bitmask.
you can use the functions and macros in the "stat" module to decipher
them.
st = os.stat(myfile)
mode = st[stat.ST_MODE]
if mode & stat.S_IREAD: # same as stat.S_IRUSR
print "readable"
if mode & stat.S_IWRITE: # same as stat.S_IWUSR
print "writable"
if mode & stat.S_IEXEC: # same as stat.S_IXUSR
print "executable"
Note that (within stat):
(S_IREAD, S_IWRITE, S_IEXEC) == (S_IRUSR, S_IWUSR, S_IXUSR)
Also note the following identities:
(S_IRUSR >> 2) == (S_IWUSR >> 1) == S_IXUSR
(S_IRGRP >> 2) == (S_IWGRP >> 1) == S_IXGRP
(S_IROTH >> 2) == (S_IWOTH >> 1) == S_IXOTH
And, for symmetry:
(S_IRUSR >> 6) == (S_IRGRP >> 3) == S_IROTH
(S_IWUSR >> 6) == (S_IWGRP >> 3) == S_IWOTH
(S_IXUSR >> 6) == (S_IXGRP >> 3) == S_IXOTH
Note as well these identities (in *NIX):
S_IRWXU == (S_IRUSR | S_IWUSR | S_IXUSR) == 0700
S_IRWXG == (S_IRGRP | S_IWGRP | S_IXGRP) == 0070
S_IRWXO == (S_IROTH | S_IWOTH | S_IXOTH) == 0007
0777 == (S_IRWXU | S_IRWXG | S_IRWXO) == 0777
Its should be obvious how the latter is equivalent to "a+rwx".
After studying the above, the following illustrative function for adding
permissions to a file might begin to make sense:
def addmodes(thepath, modes):
"""
thepath is a path to a file or directory (a str type)
modes is a tuple of modes from the stat module
"""
import operator
import stat
st = os.stat(thepath)[stat.ST_MODE]
os.chmod(thepath, reduce(operator.or_, (st,) + modes))
Problem cont.:
Thanks for your help but I only seem to be able to check whether or not
the user running the script has "rwx" permissions. I am looking to find
the permissions for owner/group/other, preferably in numeric mode.
Solution:
did you try printing the "mode" value? I'm pretty sure it does contain
the "numeric mode" you're looking for.
try this:
st = os.stat(myfile)
mode = st[stat.ST_MODE]
print "mode is", oct(mode & 0777)
(looking in the stat module source file may also help; it's in Python's
Lib directory)