暂时忽略Python中的SIGINT

时间:2017-03-14 22:04:01

标签: python sigint

我想运行一堆需要一段时间但却无法中断的命令(固件更新)。如果之前收到过sigint,我想退出。我尝试将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()

1 个答案:

答案 0 :(得分:0)

感谢评论和更多阅读,我想我理解这个问题。 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/