Linux系统中读取并设置umask(用户文件创建模式掩码)通常使用的是os模块的umask函数。然而,这个操作并不是线程安全的,因为os.umask函数会改变进程级别的umask值,在多线程环境下可能会出现竞态条件。本文主要Linux中通过Python以线程安全方式读取umask,以及简单介绍下umask。

1、umask介绍

当我们登录系统之后创建一个文件总是有一个默认权限的,那么这个权限是怎么来的呢?这就是umask干的事情。umask设置了用户创建文件的默认 权限,它与chmod的效果刚好相反,umask设置的是权限“补码”,而chmod设置的是文件权限码。一般在/etc/profile$ [HOME]/.bash_profile$[HOME]/.profile中设置umask值。

你的系统管理员必须要为你设置一个合理的umask值,以确保你创建的文件具有所希望的缺省权限,防止其他非同组用户对你的文件具有写权限。在已经登录之后,可以按照个人的偏好使用umask命 令来改变文件创建的缺省权限。相应的改变直到退出该shell或使用另外的umask命令之前一直有效。一般来说,umask命令是在/etc /profile文件中设置的,每个用户在登录时都会引用这个文件,所以如果希望改变所有用户的umask,可以在该文件中加入相应的条目。如果希望永久 性地设置自己的umask值,那么就把它放在自己$HOME目录下的.profile.bash_profile文件中。

2、通过Python读取umask

如果Linux系统中,在/proc/[pid]/status中有umask这个字段,可以使用如下代码读取,

import os
def getumask():
    pid = os.getpid()
    with open(f'/proc/{pid}/status') as f:
        for l in f:
            if l.startswith('Umask'):
                return int(l.split()[1])
        return None

测试是在CentOS 7.5Debian 9.6中。

import os
import threading

# 创建一个全局线程锁
umask_lock = threading.Lock()

def get_umask():
    with umask_lock:
        # 保存当前umask
        current_umask = os.umask(0)
        # 恢复原始umask
        os.umask(current_umask)
        return current_umask

def set_umask(new_umask):
    with umask_lock:
        os.umask(new_umask)

# 示例:读取和设置umask
if __name__ == "__main__":
    # 获取当前umask
    current_umask = get_umask()
    print(f"Current umask: {oct(current_umask)}")

    # 设置新的umask
    new_umask = 0o022
    set_umask(new_umask)
    print(f"New umask set to: {oct(new_umask)}")

    # 再次获取umask以验证
    current_umask = get_umask()
    print(f"Current umask after setting new value: {oct(current_umask)}")