os模块篇(四)

专栏目录

os.setregid(rgid, egid, /)

os.setregid(rgid, egid) 是 Python 的 os 模块中的一个函数,用于设置进程的实际组 ID(real group ID)和有效组 ID(effective group ID)。这个函数在 Unix-like 系统上有效,但在 Windows 上并不可用。

参数说明:

  • rgid: 要设置的实际组 ID。
  • egid: 要设置的有效组 ID。

调用 os.setregid(rgid, egid) 时,进程的实际组 ID 和有效组 ID 会被分别设置为 rgid 和 egid。实际组 ID 是进程创建时所属的组 ID,而有效组 ID 用于决定进程对文件的访问权限。

需要注意的是,只有具有足够权限的进程(通常是超级用户或进程的所有者)才能成功调用 os.setregid() 来改变组 ID。此外,如果进程已经是目标组 ID 的成员,则调用可能会成功;否则,可能会失败。

以下是一个使用 os.setregid() 的示例:

import os

# 获取当前进程的实际组 ID 和有效组 ID
real_gid = os.getgid()
effective_gid = os.getegid()

print(f"Current real group ID: {real_gid}")
print(f"Current effective group ID: {effective_gid}")

# 假设我们有两个目标组 ID
target_rgid = 1000  # 替换为你想设置的实际组 ID
target_egid = 2000  # 替换为你想设置的有效组 ID

try:
    # 尝试设置实际组 ID 和有效组 ID
    os.setregid(target_rgid, target_egid)
    
    # 再次获取并打印组 ID,以确认是否更改成功
    new_real_gid = os.getgid()
    new_effective_gid = os.getegid()
    
    print(f"New real group ID: {new_real_gid}")
    print(f"New effective group ID: {new_effective_gid}")
except PermissionError:
    print("Permission denied. Unable to change group IDs.")

在上面的代码中,我们首先获取了当前进程的实际组 ID 和有效组 ID,然后尝试使用 os.setregid() 设置新的组 ID。如果调用成功,将打印出新的组 ID;否则,将捕获 PermissionError 并打印错误消息。

需要注意的是,os.setregid() 函数在 Python 3.3 之后被标记为已弃用,并且在 Python 3.8 中被移除。如果你正在使用较新版本的 Python,并且需要更改组 ID,你可能需要使用 os.setgroups() 和 os.setgid() 函数来代替。os.setgroups() 可以设置进程的组访问列表,而 os.setgid() 可以设置进程的有效组 ID。

os.setreuid(ruid, euid, /)

os.setreuid(ruid, euid) 是 Python 的 os 模块中的一个函数,用于设置进程的实际用户 ID(real user ID)和有效用户 ID(effective user ID)。这个函数在 Unix-like 系统上有效,但在 Windows 上并不可用。

参数说明:

  • ruid: 要设置的实际用户 ID。
  • euid: 要设置的有效用户 ID。

调用 os.setreuid(ruid, euid) 时,进程的实际用户 ID 和有效用户 ID 会被分别设置为 ruid 和 euid。实际用户 ID 是进程创建时所属的用户 ID,而有效用户 ID 用于决定进程对文件的访问权限。

和 os.setregid() 类似,os.setreuid() 也要求调用进程具有足够的权限(通常是超级用户权限)才能成功更改用户 ID。如果进程不是目标用户 ID 的所有者,或者没有相应的权限,调用可能会失败。

需要注意的是,os.setreuid() 在 Python 3.3 之后被标记为已弃用,并且在 Python 3.8 中被移除。如果你正在使用较新版本的 Python,并且需要更改用户 ID,你应该使用 os.setuid() 函数来设置有效用户 ID,并且可能需要使用 os.setgroups() 来管理用户所属的组。

下面是一个使用 os.setreuid() 的示例(尽管该函数在 Python 3.8 之后不再可用):

import os

# 获取当前进程的实际用户 ID 和有效用户 ID
real_uid = os.getuid()
effective_uid = os.geteuid()

print(f"Current real user ID: {real_uid}")
print(f"Current effective user ID: {effective_uid}")

# 假设我们有两个目标用户 ID
target_ruid = 1000  # 替换为你想设置的实际用户 ID
target_euid = 2000  # 替换为你想设置的有效用户 ID

try:
    # 尝试设置实际用户 ID 和有效用户 ID
    os.setreuid(target_ruid, target_euid)
    
    # 再次获取并打印用户 ID,以确认是否更改成功
    new_real_uid = os.getuid()
    new_effective_uid = os.geteuid()
    
    print(f"New real user ID: {new_real_uid}")
    print(f"New effective user ID: {new_effective_uid}")
except PermissionError:
    print("Permission denied. Unable to change user IDs.")

在上面的代码中,我们首先获取了当前进程的实际用户 ID 和有效用户 ID,然后尝试使用 os.setreuid() 设置新的用户 ID。如果调用成功,将打印出新的用户 ID;否则,将捕获 PermissionError 并打印错误消息。

对于新版本的 Python,你可能需要采取其他方法来更改用户或组 ID,因为 os.setreuid() 和 os.setregid() 已经不再推荐使用

os.getsid(pid, /)

os.getsid(pid) 是 Python os 模块中的一个函数,用于获取与指定进程ID相关联的会话ID(session ID)。会话是Unix和类Unix系统中的一个概念,用于将多个进程组合在一起,以便进行会话管理和控制。

参数 pid 是一个整数,表示要查询的进程的进程ID。如果 pid 为0,则函数返回调用进程的会话ID。

这个函数返回的是一个整数,表示与给定进程ID相关联的会话ID。

示例:

import os

# 获取当前进程的会话ID
current_sid = os.getsid(0)
print(f"当前进程的会话ID: {current_sid}")

# 假设你有一个子进程的PID
child_pid = 12345

# 获取子进程的会话ID
child_sid = os.getsid(child_pid)
print(f"子进程的会话ID: {child_sid}")

在上面的示例中,os.getsid(0) 返回调用进程的会话ID,而 os.getsid(child_pid) 则返回与 child_pid 对应的子进程的会话ID。

需要注意的是,这个函数在Windows上不可用,因为Windows并没有实现Unix的会话概念。在Windows上调用 os.getsid() 将引发 AttributeError 异常。

如果你需要在Windows上获取与进程相关联的信息,可能需要使用其他API或模块,例如 ctypes 模块来调用Windows的本地API,或者 psutil 这样的第三方库来提供更跨平台的进程信息访问。

os.setsid()

os.setsid() 是 Python 的 os 模块中的一个函数,用于创建一个新的会话(session)。当调用此函数时,它会执行以下操作:

  • 创建一个新的会话,并成为该会话的领导者(leader)。
  • 该进程会成为新会话的唯一进程组成员。
  • 该进程没有控制终端(controlling terminal)。如果原先进程有一个控制终端,那么这个终端会被关闭。
  • 该进程的所有文件描述符(file descriptors)都会从原先进程的文件描述符表中继承过来,但是它们不会被复制到新的会话中。

在 Unix 和类 Unix 系统上,会话是进程组的一种扩展,它可以包括多个进程组,并且有一个会话领导者(session leader)。会话通常用于实现终端控制,例如当你打开一个终端窗口时,它会启动一个会话,并且该会话中的进程会共享终端输入和输出。

os.setsid() 通常用于创建守护进程(daemon),因为守护进程需要独立于控制终端运行。通过调用 os.setsid(),进程可以脱离原有的会话和控制终端,从而确保它不会在终端关闭时被终止。

以下是一个使用 os.setsid() 创建守护进程的简单示例:

import os
import sys

def daemonize():
    # 创建新的会话并成为会话领导者
    try:
        pid = os.setsid()
    except OSError:
        sys.stderr.write("Failed to create a new session.\n")
        sys.exit(1)

    # 忽略 SIGHUP 信号
    os.signal(os.SIGHUP, os.SIG_IGN)

    # 更改当前工作目录到根目录
    os.chdir("/")

    # 重定向标准输入、输出和错误到 /dev/null
    os.umask(0)
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

# 调用守护进程创建函数
daemonize()

# 现在可以继续执行守护进程的任务
while True:
    # ... 执行你的守护进程代码 ...
    pass

在上面的示例中,daemonize() 函数创建了一个新的会话,并设置了守护进程所需的其他属性,如忽略 SIGHUP 信号、更改工作目录、重定向标准输入/输出/错误等。调用 daemonize() 后,进程就变成了一个守护进程,可以独立于控制终端运行。

os.setuid(uid, /)

os.setuid(uid) 是 Python 的 os 模块中的一个函数,用于设置进程的有效用户 ID(effective user ID)。在 Unix 和类 Unix 系统上,用户 ID 是一个用于标识进程所有者的数字。有效用户 ID 用于决定进程对文件的访问权限。

参数 uid 是一个整数,表示要设置的有效用户 ID。

调用 os.setuid(uid) 时,进程的有效用户 ID 会被设置为 uid。这意味着进程将以 uid 指定的用户身份运行,并且对于文件访问和其他系统操作,它将以该用户的权限来执行。

需要注意的是,只有特权进程(通常是超级用户或 root 用户启动的进程)才能更改其有效用户 ID。如果进程没有足够的权限来更改用户 ID,os.setuid() 调用将会失败,并可能抛出 PermissionError 异常。

此外,os.setuid() 设置的只是有效用户 ID,而不是实际用户 ID(real user ID)。实际用户 ID 通常是进程创建时所属的用户 ID,通常不会改变。有效用户 ID 的改变会影响进程的文件访问权限,但不会改变进程的所有者身份。

下面是一个使用 os.setuid() 的示例:

import os

# 获取当前进程的有效用户 ID
current_uid = os.geteuid()

print(f"Current effective user ID: {current_uid}")

# 假设我们有一个目标用户 ID
target_uid = 1000  # 替换为你想设置的有效用户 ID

try:
    # 尝试设置有效用户 ID
    os.setuid(target_uid)
    
    # 再次获取并打印有效用户 ID,以确认是否更改成功
    new_uid = os.geteuid()
    
    print(f"New effective user ID: {new_uid}")
except PermissionError:
    print("Permission denied. Unable to change user ID.")

在上面的代码中,我们首先获取了当前进程的有效用户 ID,然后尝试使用 os.setuid() 将其更改为 target_uid。如果更改成功,我们将再次获取并打印新的有效用户 ID。如果进程没有足够的权限来更改用户 ID,则会捕获 PermissionError 异常并打印相应的错误消息。

请注意,os.setuid() 在现代 Unix 系统上通常被认为是不安全的,因为它允许进程提升其权限。因此,在编写需要更改用户 ID 的代码时,应该非常小心,并确保只在必要时使用此功能,并且只由特权进程执行。

os.strerror(code, /)

os.strerror(code) 是 Python 的 os 模块中的一个函数,用于根据给定的错误码(通常是一个整数)检索对应的错误消息字符串。这个错误码通常是由某些系统调用或库函数在出错时返回的。

例如,当你尝试打开一个不存在的文件时,os.open() 函数可能会返回一个错误码,你可以使用 os.strerror() 来获取与该错误码对应的描述性错误消息。

这里是一个简单的示例:

import os

# 尝试打开一个不存在的文件
try:
    fd = os.open('nonexistent_file.txt', os.O_RDONLY)
except OSError as e:
    # 获取错误码
    error_code = e.errno
    # 使用 os.strerror() 获取错误消息
    error_message = os.strerror(error_code)
    print(f"发生错误: {error_message}")

在上面的示例中,如果 ‘nonexistent_file.txt’ 文件不存在,os.open() 将引发一个 OSError 异常,并且 e.errno 将包含一个错误码。然后,我们使用 os.strerror(error_code) 来获取并打印出相应的错误消息。

需要注意的是,os.strerror() 返回的错误消息是特定于平台的,因为它依赖于底层操作系统的错误消息。在不同的操作系统或不同的语言环境中,相同的错误码可能对应不同的错误消息。

此外,os.strerror() 还可以接受一个可选的第二个参数,该参数指定错误消息的语言环境。这在处理国际化(i18n)和本地化(l10n)问题时可能很有用。然而,在大多数常见用法中,可以省略这个参数。

os.umask(mask, /)

os.umask(mask) 是 Python 中 os 模块的一个函数,用于设置或获取当前进程的 umask 值。umask(用户文件创建掩码)是一个八进制数,用于控制新创建的文件和目录的默认权限。

当你调用 os.umask(mask) 时,如果 mask 参数被指定,那么它会设置当前进程的 umask 值。如果 mask 参数未指定,那么函数会返回当前进程的 umask 值。

umask 的作用是限制新创建的文件和目录的权限。当文件或目录被创建时,其权限会与 umask 进行按位与(AND)操作,从而得到最终的权限。

umask 的值通常是一个八进制数,其各位代表不同的权限:

  • 第 0 位代表特殊权限(setuid, setgid, sticky bit),通常设置为 0。
  • 第 1-3 位代表其他用户的读权限(others read)。
  • 第 4-6 位代表其他用户的写权限(others write)。
  • 第 7-9 位代表其他用户的执行权限(others execute)。

同样地,umask 的值也可以用符号表示法来指定,例如 ‘022’ 或 ‘u=rwx,g=rx,o=rx’。

下面是一个使用 os.umask() 的示例:

import os

# 获取当前的 umask 值
current_umask = os.umask(0)  # 传入 0 以获取当前 umask 值
print(f"Current umask: {current_umask:03o}")  # 打印 umask 值,格式化为三位八进制数

# 设置新的 umask 值
new_umask = 0o177  # 设置 umask 为 0177,即只有文件所有者有读写执行权限
os.umask(new_umask)

# 创建新文件或目录,检查其权限
# 注意:这里只是演示 umask 的效果,实际上不会真正创建文件或目录
print("New file/directory permissions will be limited by the umask.")

# 再次获取 umask 值以确认更改
confirmed_umask = os.umask(0)
print(f"Confirmed umask: {confirmed_umask:03o}")

在上面的代码中,我们首先获取了当前的 umask 值,然后设置了一个新的 umask 值,并打印了设置后的 umask 值以确认更改。需要注意的是,umask 的设置会影响之后创建的文件和目录的默认权限,但不会影响已经存在的文件或目录的权限。

在实际应用中,umask 的设置通常用于控制文件和目录的安全性,确保只有必要的用户能够访问和修改它们。

os.uname()

os.uname() 是 Python 的 os 模块中的一个函数,用于返回当前操作系统的详细信息。这个函数在 Unix-like 系统(如 Linux、macOS 等)上特别有用,因为它提供了关于底层操作系统的各种信息。

os.uname() 返回一个包含五个字段的元组,这些字段描述了操作系统的名称、网络节点主机名、发布号、版本号和机器硬件名称。这些字段分别对应元组的五个元素:

  • sysname:操作系统的名称。例如,对于 Linux,这通常是 ‘Linux’。
  • nodename:网络节点主机名。这通常是当前计算机的主机名。
  • release:操作系统的发布号。这通常是操作系统的版本号或发行版信息。
  • version:操作系统的版本。这可以包括关于内核版本或其他相关软件版本的详细信息。
  • machine:硬件名称。这描述了计算机的硬件架构,例如 ‘x86_64’。

下面是一个使用 os.uname() 的简单示例:

import os

# 获取操作系统信息
uname_info = os.uname()

# 打印信息
print(f"System name: {uname_info.sysname}")
print(f"Node name: {uname_info.nodename}")
print(f"Release: {uname_info.release}")
print(f"Version: {uname_info.version}")
print(f"Machine: {uname_info.machine}")

需要注意的是,os.uname() 在 Windows 上不可用,因为它是一个 Unix-specific 的函数。在 Windows 上,你可以使用其他方法(如 platform 模块)来获取类似的信息。

此外,虽然 os.uname() 提供了丰富的操作系统信息,但在许多应用中,你可能不需要所有这些细节。如果你只是想要检查你的代码是否在特定的操作系统上运行,使用 os.name 或 platform 模块可能更简单且更直接。

os.unsetenv(key, /)

os.unsetenv(key) 是 Python 的 os 模块中的一个函数,用于从当前进程的环境变量中删除指定的环境变量。这个函数在 Unix 和类 Unix 系统(如 Linux 和 macOS)上可用,但在 Windows 上不可用。

在 Windows 上,应该使用 os.environ 字典来删除环境变量,例如 del os.environ[key]。

os.unsetenv 函数的参数 key 是一个字符串,表示要删除的环境变量的名称。

下面是一个使用 os.unsetenv 的例子:

import os

# 检查环境变量是否存在
if 'MY_ENV_VAR' in os.environ:
    # 删除环境变量
    os.unsetenv('MY_ENV_VAR')
    print("Environment variable MY_ENV_VAR has been unset.")
else:
    print("Environment variable MY_ENV_VAR does not exist.")

请注意,删除环境变量可能会影响当前进程及其子进程的行为,因为环境变量通常用于配置操作系统和应用程序的行为。

在 Windows 上,你可以这样做:

import os

# 检查环境变量是否存在
if 'MY_ENV_VAR' in os.environ:
    # 删除环境变量
    del os.environ['MY_ENV_VAR']
    print("Environment variable MY_ENV_VAR has been unset.")
else:
    print("Environment variable MY_ENV_VAR does not exist.")

在实际应用中,你可能需要谨慎地管理环境变量,以避免意外地改变程序的行为或导致不可预测的错误。在删除环境变量之前,最好先确认它确实存在,并且了解其删除可能带来的影响。

os.unshare(flags)

os.unshare() 是 Python 的 os 模块中的一个函数,它用于修改已经存在的进程的共享属性。通过这个函数,你可以更改进程的某些资源是否与其他进程共享,比如文件系统、命名空间等。

os.unshare() 函数接受一个标志参数 flags,这个参数是一个整数,用于指定要更改的共享属性。不同的操作系统和平台可能支持不同的标志。

以下是一些常见的标志值(在 Linux 上):

  • os.CLONE_FS: 更改文件系统的共享属性。如果设置了这个标志,那么调用 os.unshare() 的进程将获得一个独立的文件系统挂载命名空间,这意味着它可以有自己的挂载点和卸载点,与其他进程隔离。
  • os.CLONE_NEWIPC: 更改进程间通信(IPC)对象的共享属性。设置这个标志后,进程将拥有独立的 IPC 命名空间,这意味着它可以有自己的信号量、消息队列和共享内存对象,与其他进程隔离。
  • os.CLONE_NEWNET: 更改网络命名空间的共享属性。设置这个标志后,进程将拥有独立的网络命名空间,这意味着它可以有自己的网络接口、路由表等,与其他进程隔离。
  • os.CLONE_NEWPID: 更改进程ID命名空间的共享属性。设置这个标志后,进程将拥有独立的进程ID空间,这意味着它可以有自己的进程ID,与其他进程隔离。
  • os.CLONE_NEWNS: 更改挂载命名空间的共享属性。设置这个标志后,进程将拥有独立的挂载命名空间,与其他进程隔离。
  • os.CLONE_NEWUSER: 更改用户命名空间的共享属性。设置这个标志后,进程将拥有独立的用户命名空间,这意味着它可以有自己的用户ID和组ID映射,与其他进程隔离。
  • os.CLONE_NEWUTS: 更改 UTS(UNIX Time Sharing)命名空间的共享属性。设置这个标志后,进程将拥有独立的 UTS 命名空间,这意味着它可以有自己的主机名和域名,与其他进程隔离。

调用 os.unshare() 时,需要传递适当的标志,以更改你希望隔离的命名空间。例如,如果你想创建一个拥有独立文件系统挂载命名空间的进程,你可以这样做:

import os

if os.unshare(os.CLONE_FS):
    # 这里是隔离后的进程代码
    pass
else:
    # os.unshare() 调用失败,处理错误
    pass

请注意,os.unshare() 在 Windows 上是不可用的。此外,在使用 os.unshare() 时,你应当注意修改进程的共享属性可能会涉及到复杂的系统编程和操作系统知识,因此在使用之前最好详细了解相关的概念和限制。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值