gpt4 book ai didi

python - 在 Python 中覆盖基本信号(SIGINT、SIGQUIT、SIGKILL??)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:00:43 25 4
gpt4 key购买 nike

我正在编写一个程序,根据我们公司的政策添加普通 UNIX 帐户(即修改/etc/passwd、/etc/group 和/etc/shadow)。它还会做一些稍微花哨的事情,例如向用户发送电子邮件。

我已经让所有代码正常工作,但是有三段代码非常关键,它们更新了上面的三个文件。该代码已经相当健壮,因为它锁定了这些文件(例如/etc/passwd.lock),写入临时文件(例如/etc/passwd.tmp),然后用临时文件覆盖原始文件。我很高兴它不会干扰我程序的其他运行版本或系统 useradd、usermod、passwd 等程序。

我最担心的是这些部分中间的杂乱的 ctrl+c、ctrl+d 或 kill 命令。这让我找到了信号模块,它似乎正是我想要的:在“关键”区域忽略某些信号。我使用的是旧版本的 Python,它没有 signal.SIG_IGN,所以我有一个很棒的“传递”函数:

def passer(*a):
pass

我看到的问题是信号处理程序没有按我期望的方式工作。给定以下测试代码:

def passer(a=None, b=None):
pass

def signalhander(enable):
signallist = (signal.SIGINT, signal.SIGQUIT, signal.SIGABRT, signal.SIGPIPE, signal.SIGALRM, signal.SIGTERM, signal.SIGKILL)
if enable:
for i in signallist:
signal.signal(i, passer)
else:
for i in signallist:
signal.signal(i, abort)
return


def abort(a=None, b=None):
sys.exit('\nAccount was not created.\n')
return
signalhander(True)
print('Enabled')
time.sleep(10) # ^C during this sleep

此代码的问题在于 time.sleep(10) 调用期间的 ^C (SIGINT) 导致该函数停止,然后,我的信号处理程序按需要接管。但是,这并不能解决我上面的“关键”区域问题,因为我不能容忍任何语句遇到失败信号。

我需要某种可以完全忽略 SIGINT 和 SIGQUIT 的信号处理程序。Fedora/RH 命令“yum”是用 Python 编写的,基本上完全符合我的要求。如果你在安装任何东西时执行 ^C,它会打印一条消息,如“在两秒钟内按 ^C 以强制终止”。否则,^C 将被忽略。我真的不关心两秒警告,因为我的程序在几分之一秒内完成。

有人可以帮我实现 CPython 2.3 的信号处理程序,它不会导致当前语句/函数在信号被忽略之前取消吗?

一如既往,提前致谢。


编辑:在 S.Lott 的回答之后,我决定放弃信号模块。

我要回到 try: except: block 。查看我的代码,每个无法中止的关键区域都会发生两件事:用 file.tmp 覆盖文件并在完成后删除锁定(否则其他工具将无法修改该文件,直到它被手动删除)。我将它们中的每一个都放在了 try: block 中各自的函数中,而 except: 只是再次调用该函数。这样,函数将在 KeyBoardInterruptEOFError 事件中重新调用自身,直到关键代码完成。我认为我不会遇到太多麻烦,因为我只捕获用户提供的退出命令,即便如此,也只有两到三行代码。从理论上讲,如果可以足够快地引发这些异常,我想我可以得到“超过最大递归深度”错误,但这似乎很遥远。

还有其他问题吗?

伪代码:

def criticalRemoveLock(file):
try:
if os.path.isFile(file):
os.remove(file)
else:
return True
except (KeyboardInterrupt, EOFError):
return criticalRemoveLock(file)
def criticalOverwrite(tmp, file):
try:
if os.path.isFile(tmp):
shutil.copy2(tmp, file)
os.remove(tmp)
else:
return True
except (KeyboardInterrupt, EOFError):
return criticalOverwrite(tmp, file)

最佳答案

没有真正的方法可以让您的脚本真正保存下来。当然,您可以忽略信号并使用 try: except: 捕获键盘中断,但是您的应用程序是否能够对此类中断进行幂等处理,并且它必须能够在处理中断后恢复操作某种保存点。

您真正可以做的唯一一件事就是处理临时文件(而不是原始文件),并在完成工作后将它们移动到最终目的地。我认为从文件系统的角度来看,这样的文件操作应该是“原子的”。否则,如果发生中断:从干净的数据开始重新开始处理。

关于python - 在 Python 中覆盖基本信号(SIGINT、SIGQUIT、SIGKILL??),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5711745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com