【问题标题】:Temporarily ignore SIGINT in Python在 Python 中暂时忽略 SIGINT
【发布时间】:2017-03-14 22:04:00
【问题描述】:

我想运行一堆需要一段时间但不能中断的命令(固件更新)。如果之前收到信号,我想退出。我尝试将 signal.SIG_IGN 替换为每次收到 SIGINT 时都会计数的类,但在类迭代其计数器后,SIGINT 仍将通过主 Python 脚本。

忽略它很容易工作:

import subprocess
import signal

def dont_interrupt_me():
    """Run bash command."""
    print "Keyboard interrupt ignored during update process."
    # Stops keyboard interrupts during the Popen
    sigint_stopper = signal.signal(signal.SIGINT, signal.SIG_IGN)
    bash_cmd = subprocess.Popen(['sleep', '10'])
    bash_cmd.wait()
    install_return_code = bash_cmd.returncode
    # Return signint to normal
    signal.signal(signal.SIGINT, sigint_stopper)
    # if ctrl_c_earlier:
    #    sys.exit(1)
    return install_return_code

for each in range(1,10):
    dont_interrupt_me()

我的 SigintIgnore 类尝试不是不起作用:

import subprocess
import signal

class SigintIgnore(object):
    """Count the number of sigint's during ignore phase."""
    def __init__(self):
        """Init count to 0."""
        self.count = 0
        self.exit_amount = 10
    def __call__(self, first, second):
        """Init count to 0."""
        self.count += 1
        print "\nself.count: " + str(self.count)
        print "first: " + str(first)
        print "second: " + str(second)
        if self.count > 1:
            print("Press 'ctrl + c' " +
                  str(self.exit_amount - self.count) +
                  " more times to force exit.")
        if self.count > self.exit_amount:
            sys.exit(EXIT_USER_CHOICE)


def dont_interrupt_me():
    """Run bash command."""
    counter = SigintIgnore()
    print "Keyboard interrupt ignored during update process."
    sigint_stopper = signal.signal(signal.SIGINT, counter)
    # Stops keyboard interrupts during the update calls
    bash_cmd = subprocess.Popen(['sleep', '10'])
    bash_cmd.wait()
    install_return_code = bash_cmd.returncode
    signal.signal(signal.SIGINT, sigint_stopper)
    if counter.count > 1:
        sys.exit(1)
    return install_return_code


for each in range(1,10):
    dont_interrupt_me()

【问题讨论】:

  • 您的 SigintIgnore 课程有什么具体问题?
  • @user2357112:根据 OP 问题顶部的文字,听起来KeyboardInterrupt 仍在上升。
  • @Kevin:这可能是他们想说的,但很难说。还有其他合理的解读。无论如何,我认为不会是 KeyboardInterrupt 在这里提出的;可能是 IOError 什么的,但 KeyboardInterrupt 不太可能。
  • 您使用的是哪个 Python 版本? Signal handling behavior changed in 3.5,虽然我不知道更改是否达到subprocess.Popen.wait
  • Python 2.7。它看起来不像 IOError,因为我没有尝试,但它仍然退出而不抛出任何东西。

标签: python sigint


【解决方案1】:

感谢 cmets 和更多阅读,我想我理解了这个问题。 SIG_IGN 版本将完全阻止信号通过。该类将在哪里捕获 SIGINT 中断,但该中断仍会使其进入 sleep 30 / unix 命令? unix 命令退出,但 python 代码忽略中断。这部分我不是 100%,但是杀死 unix 命令的中断可能是中断的系统调用,或 EINTR,或 IOError。所以不一定是 SIGINT 本身,而是 SIGINT 的副产品?

我认为这些链接可能会提供一些额外的详细信息: What is the proper way to handle (in python) IOError: [Errno 4] Interrupted system call, raised by multiprocessing.Queue.get

https://www.python.org/dev/peps/pep-0475/

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2021-10-17
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    相关资源
    最近更新 更多