【问题标题】:How can I get the Unix permission mask from a file? [duplicate]如何从文件中获取 Unix 权限掩码? [复制]
【发布时间】:2011-07-17 06:17:45
【问题描述】:

如何使用 python 在 *nix 上获取文件的权限掩码,如 644 或 755?

是否有任何功能或类可以做到这一点?非常感谢!

【问题讨论】:

    标签: python file-permissions user-permissions


    【解决方案1】:

    我确定 os 模块中有很多基于文件的函数。如果你运行os.stat(filename),你总是可以解释结果。

    http://docs.python.org/library/stat.html

    【讨论】:

      【解决方案2】:

      os.stat类似于c-lib stat(linux上man 2 stat看资料)

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

      【讨论】:

        【解决方案3】:

        如果您不想弄清楚 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
        

        【讨论】:

          【解决方案4】:
          oct(os.stat('file').st_mode)[4:]
          

          【讨论】:

            【解决方案5】:

            os.statstat(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)
            

            【讨论】:

            • 很好的答案,非常感谢!
            • 我最喜欢这个答案,但位掩码似乎比字符串切片更干净:oct(os.stat("test.txt").st_mode & 0777)
            • @miku 以及如何对文件应用任何权限,假设我要设置权限755
            • oct(os.stat("test.txt")[ST_MODE])[-3:] 在 OSX 上不起作用。而是使用 oct(os.stat("test.txt")[0])[-3:] 或 .st_mode & 0777
            • @user3329564 它对我有用 - ST_MODEstat 模块中,你导入了吗?
            【解决方案6】:

            我认为这是获取文件权限位的最清晰方法:

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

            os.lstat 函数将在文件是符号链接的情况下为您提供链接本身的模式,而 os.stat 取消引用链接。因此,我发现os.lstat 最普遍有用。

            这是一个示例,给定常规文件“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
            

            【讨论】:

            • 感谢您指出statlstat 的区别。
            • @devsnd 很高兴能提供帮助。
            • 请注意,在Python 3 中有new syntax for octalsthus 上面示例的输出是:0o7770o666 而不是07770666。跨度>
            【解决方案7】:

            os.access(path, mode) 方法返回 True 如果路径上允许访问,则返回 False 否则。

            可用的模式有:

            1. os.F_OK - 测试路径是否存在。
            2. os.R_OK - 测试路径的可读性。
            3. os.W_OK - 测试路径的可写性。
            4. os.X_OK - 测试路径是否可以执行。

            例如检查文件/tmp/test.sh是否有执行权限

            ls -l /tmp/temp.sh
            -rw-r--r--  1 *  *  0 Mar  2 12:05 /tmp/temp.sh
            
            os.access('/tmp/temp.sh',os.X_OK)
            False
            
            after changing the file permission to +x 
            chmod +x /tmp/temp.sh
            
            ls -l /tmp/temp.sh
            -rwxr-xr-x  1 *  *  0 Mar  2 12:05 /tmp/temp.sh
            
            os.access('/tmp/temp.sh',os.X_OK)
            True
            

            【讨论】:

              【解决方案8】:

              如果需要,您可以使用 Popen 运行 Bash stat 命令:

              普通的 Bash 命令:

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

              然后使用 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
              '664'
              

              如果您想搜索目录,还有另一种方法:

              >>> 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)
                      break
              ... 
              664
              >>> 
              

              【讨论】:

              • 虽然“你可以”是真的,但你真的不应该这样做,除非你正在编写一次性脚本并且你根本不关心性能。每次python程序需要访问文件的权限时,此方法都会创建一个新进程。创建新流程是一项繁重的操作,应尽可能避免。而且由于在这种情况下绝对有可能,因此这个答案给出了不好的建议。
              【解决方案9】:

              这是一个检查目录权限的简单方法。

              import os
              import stat
              
              mode = os.stat("path_of_directory").st_mode
              
              if not ((mode & stat.S_IWUSR):
                print('not writable by user')
              
              if not ((mode & stat.S_IWUSR) and (mode & stat.S_IWGRP) and (mode & stat.S_IWOTH)):
                print('not writable by all')
              

              标志列表如下:

              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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-08-30
                • 2017-06-15
                • 1970-01-01
                • 2016-06-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-09-23
                相关资源
                最近更新 更多