【问题标题】:Why the first letter of stat.filemode is `?`?为什么 stat.filemode 的第一个字母是 `?`?
【发布时间】:2020-01-04 03:13:54
【问题描述】:

我看到?stat.filemode() 结果的第一个字母。但是我不记得在普通的linux系统中我见过?作为第一个字母。

https://en.wikipedia.org/wiki/Chmod

? 代表什么?如何将- 作为第一个字母?谢谢。

#!/usr/bin/env bash

printMode() {
  local mode; mode=$1; shift
  printf '%s\t' "$@"
  python3 -c 'import stat, sys; print(stat.filemode(int(sys.argv[1])))' "$mode"
}

printMode 0 0
for ((i=1;i<16;++i)); do
    printMode "$((2**(i-1)))" "$i"
done

for ((i=0;i<=2;++i)); do
    printMode "$((2**(i*3) + 2**(9+i)))" "$((i*3+1))" "$((10+i))"
done
0   ?---------
1   ?--------x
2   ?-------w-
3   ?------r--
4   ?-----x---
5   ?----w----
6   ?---r-----
7   ?--x------
8   ?-w-------
9   ?r--------
10  ?--------T
11  ?-----S---
12  ?--S------
13  p---------
14  c---------
15  d---------
1   10  ?--------t
4   11  ?-----s---
7   12  ?--s------

【问题讨论】:

  • stat.mode() 旨在处理os.stat() 返回的模式。给它与实际模式不对应的随机数会产生奇怪的行为。
  • 2**15 返回d 的位置是哪个操作系统? stat 位的含义是每个操作系统供应商,因此没有全局规范规则。 (这就是为什么人们总是应该使用宏而不是尝试自己硬编码位掩码值,因此 Python 为这些 C 宏提供包装器)。

标签: python stat


【解决方案1】:

您在正常使用中看不到这一点,因为实际的文件模式并不是那么低的数字。文件模式包括除了权限之外的附加位,用于指示文件的类型,例如块特殊文件、字符特殊文件、目录、命名管道、常规文件、符号链接或套接字。

设置普通文件的位时,第一个字符是-;如果设置了目录的位,则为d

您使用的数字没有设置这些位,因此stat.filemode() 不知道类型是什么,并返回?。除非文件系统已损坏,否则您永远不应在目录列表中看到此内容。

【讨论】:

    【解决方案2】:

    这是在cpython/Modules/_stat.c 中定义的。引用其中的缩短部分:

    static char
    filetype(mode_t mode)
    {
        /* common cases first */
        if (S_ISREG(mode))  return '-';
        // ...lots of other cases here, for directories, symlinks, sockets, etc... //
        return '?';
    }
    

    如果您没有为S_ISREG(常规文件)或任何其他类型的文件系统对象设置该位,则测试将通过默认的?

    查看What is S_ISREG(), and what does it do?的讨论。


    在 Linux 上,相关位是 2**15:

    $ printMode "$((2**15))"
            ----------
    

    ...但是要获取当前操作系统的候选位列表,您应该调用os.stat()

    【讨论】:

    • 我已经扫描了所有的位。为什么我看不到-(或者当 S_ISREG() 为真时)?
    • 常规文件位(在 Linux 上)是 2**15printMode $((2**15))确实返回一个以-开头的字符串。
    • @user1424739, ...如果您想知道S_ISREG对于您本地安装的操作系统,请致电os.stat() 并查看哪些位高.
    猜你喜欢
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2018-07-09
    • 2015-08-06
    • 2021-01-22
    相关资源
    最近更新 更多