您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用KeyboardInterrupt异常捕获SIGINT在终端中起作用,而不在脚本中起作用

使用KeyboardInterrupt异常捕获SIGINT在终端中起作用,而不在脚本中起作用

有一种情况是在启动时 安装认的sigint处理程序,也就是在程序启动时包含信号掩码SIG_IGNfor的SIGINT情况。可以在这里找到负责此操作的代码

被忽略信号的信号掩码从父进程继承,而已处理信号重置为SIG_DFL。因此,在这种情况下,如果SIGINT忽略了if (Handlers[SIGINT].func == DefaultHandler)源中的条件不会触发并且未安装认处理程序的情况,则python不会覆盖父进程所做的设置。

因此,让我们尝试显示不同情况下使用的信号处理程序:

# invocation from interactive shell
$ python -c "import signal; print(signal.getsignal(signal.SIGINT))"
<built-in function default_int_handler>

# background job in interactive shell
$ python -c "import signal; print(signal.getsignal(signal.SIGINT))" &
<built-in function default_int_handler>

# invocation in non interactive shell
$ sh -c 'python -c "import signal; print(signal.getsignal(signal.SIGINT))"'
<built-in function default_int_handler>

# background job in non-interactive shell
$ sh -c 'python -c "import signal; print(signal.getsignal(signal.SIGINT))" &'
1

因此,在最后一个示例中,SIGINT将其设置为1(SIG_IGN)。这与在Shell脚本中启动后台作业时相同,因为认情况下它们是非交互式的(除非您-i在shebang中使用该选项)。

因此,这是由外壳程序在非交互式外壳程序会话中启动后台作业时忽略信号引起的,而不是由python直接引起的。至少bashdash这样的行为,我没有尝试过其他炮弹。

有两种方法可以处理这种情况:

手动安装认信号处理程序:

import signal

signal.signal(signal.SIGINT, signal.default_int_handler)

-i选项添加到shell脚本的shebang中,例如:

#!/bin/sh -i

编辑:bash手册中记录了此行为:

信号 … 当作业控制无效时,除了这些继承的处理程序之外,异步命令还会忽略SIGINT和SIGQUIT。

它适用于非交互式Shell,因为它们认情况下已禁用作业控制,并且实际上是在POSIX中指定的:Shell命令语言

其他 2022/1/1 18:44:37 有432人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶