如何从文件获取Unix权限掩码?

70 投票
9 回答
67159 浏览
提问于 2025-04-16 13:53

我怎么能用Python在*unix系统上获取一个文件的权限掩码,比如644或者755呢?

有没有什么函数或者类可以做到这一点?非常感谢!

9 个回答

9

如果你不想搞清楚stat是什么意思,另一种方法是使用os.access命令。你可以在这个链接找到相关信息:http://docs.python.org/library/os.html#os.access不过,记得查看一下文档,了解可能的安全问题。

比如说,你可以用它来检查一个名为test.dat的文件的权限,这个文件是可以读和写的。

os.access("test.dat",os.R_OK)
>>> True

#Execute permissions
os.access("test.dat",os.X_OK)
>>> 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
56

我觉得获取文件权限的方式就是这样最简单明了:

stat.S_IMODE(os.lstat("file").st_mode)

如果文件是一个符号链接(symlink),那么使用 os.lstat() 可以得到链接本身的权限信息,而 os.stat() 则会跟随链接去获取实际文件的权限。因此,我觉得 os.lstat() 是最常用的。

stat.S_IMODE() 可以获取“文件的权限位,还有一些其他的标志,比如粘滞位、组ID和用户ID位”。

这里有一个例子,假设有一个普通文件叫 "testfile",还有一个指向它的符号链接 "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))

这个脚本给我的输出是:

0777
0666
125

os.stat 是一个封装了 stat(2) 系统调用的工具。

>>> 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 ...
33188

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

在这里,你会看到常见的八进制权限设置。

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

其实你只需要关注较低的 ,所以可以把其他部分去掉:

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

顺便提一下,较高的部分决定了文件的类型,比如:

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)

撰写回答