python – How can I get the Unix permission mask from a file?-ThrowExceptions

Exception or error:

How can I get a file’s permission mask like 644 or 755 on *nix using python?

Is there any function or class for doing that? Thank you very much!

How to solve:

os.stat is a wrapper around the stat(2) system call interface.

>>> import os
>>> from stat import *
>>> os.stat("test.txt") # returns 10-tupel, you really want the 0th element ...
posix.stat_result(st_mode=33188, st_ino=57197013, \
    st_dev=234881026L, st_nlink=1, st_uid=501, st_gid=20, st_size=0, \
    st_atime=1300354697, st_mtime=1300354697, st_ctime=1300354697)

>>> os.stat("test.txt")[ST_MODE] # this is an int, but we like octal ...

>>> oct(os.stat("test.txt")[ST_MODE])

From here you’ll recognize the typical octal permissions.

S_IRWXU 00700   mask for file owner permissions
S_IRUSR 00400   owner has read permission
S_IWUSR 00200   owner has write permission
S_IXUSR 00100   owner has execute permission
S_IRWXG 00070   mask for group permissions
S_IRGRP 00040   group has read permission
S_IWGRP 00020   group has write permission
S_IXGRP 00010   group has execute permission
S_IRWXO 00007   mask for permissions for others (not in group)
S_IROTH 00004   others have read permission
S_IWOTH 00002   others have write permission
S_IXOTH 00001   others have execute permission

You are really only interested in the lower bits, so you could chop off the rest:

>>> oct(os.stat("test.txt")[ST_MODE])[-3:]
>>> # or better
>>> oct(os.stat("test.txt").st_mode & 0o777)

Sidenote: the upper parts determine the filetype, e.g.:

S_IFMT  0170000 bitmask for the file type bitfields
S_IFSOCK    0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)


I think this is the clearest way of getting a file’s the permission bits:


The os.lstat function, will in case the file is a symlink, give you the mode of the link itself, whereas os.stat dereferences the link. Therefore I find os.lstat the most generally useful.

Here’s an example case, given regular file “testfile” and symlink to the latter, “testlink”:

import stat
import os

print oct(stat.S_IMODE(os.lstat("testlink").st_mode))
print oct(stat.S_IMODE(os.stat("testlink").st_mode))

This script outputs the following for me:



Another way to do it if you don’t want to work out what stat means is to use the os.access command
BUT read the docs about possible security issues

For instance to check permissions on the file test.dat which has read/write permissions

>>> True

#Execute permissions
>>> False

#And Combinations thereof
os.access("test.dat",os.R_OK or os.X_OK)
>>> True

os.access("test.dat",os.R_OK and os.X_OK)
>>> False




There are a lot of file based functions inside the os module im sure. If you run os.stat(filename) you can always interprate the results.


os.stat is analogous to the c-lib stat (man 2 stat on linux to see the information)

stats = os.stat('file.txt')
print stats.st_mode


os.access(path, mode) method returns True if access is allowed on path, False if not.

available modes are :

  1. os.F_OK – test the existence of path.
  2. os.R_OK – test the readability of path.
  3. os.W_OK – test the writability of path.
  4. os.X_OK – test if path can be executed.

for example, checking file /tmp/ has execute permission

ls -l /tmp/
-rw-r--r--  1 *  *  0 Mar  2 12:05 /tmp/


after changing the file permission to +x 
chmod +x /tmp/

ls -l /tmp/
-rwxr-xr-x  1 *  *  0 Mar  2 12:05 /tmp/



You can just run a Bash stat command with Popen if you want:

The normal Bash command:

jlc@server:~/NetBeansProjects/LineReverse$ stat -c '%A %a %n' revline.c
-rw-rw-r-- 664 revline.c

And then with Python:

>>> from subprocess import Popen, PIPE
>>> fname = 'revline.c'
>>> cmd = "stat -c '%A %a %n' " + fname
>>> out = Popen(cmd, shell=True, stdout=PIPE).communicate()[0].split()[1].decode()
>>> out

And here’s another way if you feel like searching the directory:

>>> from os import popen
>>> cmd = "stat -c '%A %a %n' *"
>>> fname = 'revline.c'
>>> for i in popen(cmd):
...     p, m, n = i.split()
...     if n != fname:
...         continue
...     print(m)

Leave a Reply

Your email address will not be published. Required fields are marked *