Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用键盘中断异常捕获SIGINT在终端中工作,而不是在脚本中_Python_Bash_Shell_Sigint - Fatal编程技术网

Python 使用键盘中断异常捕获SIGINT在终端中工作,而不是在脚本中

Python 使用键盘中断异常捕获SIGINT在终端中工作,而不是在脚本中,python,bash,shell,sigint,Python,Bash,Shell,Sigint,我试图在Python2.7程序中捕获SIGINT(或键盘中断)。这就是我的Python测试脚本test的外观: #!/usr/bin/python import time try: time.sleep(100) except KeyboardInterrupt: pass except: print "error" 接下来我有一个shell脚本test.sh: ./test & pid=$! sleep 1 kill -s 2 $pid 当我使用bash

我试图在Python2.7程序中捕获SIGINT(或键盘中断)。这就是我的Python测试脚本
test
的外观:

#!/usr/bin/python

import time

try:
    time.sleep(100)
except KeyboardInterrupt:
    pass
except:
    print "error"
接下来我有一个shell脚本
test.sh

./test & pid=$!
sleep 1
kill -s 2 $pid
当我使用bash、sh或其他
bash test.sh
运行脚本时,Python进程
test
将保持运行,并且不能使用
SIGINT
终止。而当我复制
test.sh
命令并将其粘贴到(bash)终端时,Python进程
test
会关闭

我不知道发生了什么,我想了解。那么,区别在哪里,为什么

这不是关于如何在Python中捕获
SIGINT
!根据–这是可行的方法:

Python默认安装少量信号处理程序:SIGPIPE。。。SIGINT被转换为键盘中断异常


如果程序直接从shell启动,当
kill
发送
SIGINT
时,它确实捕获了
KeyboardInterrupt
,但是当程序从后台运行的bash脚本启动时,似乎从未引发键盘中断。

有一种情况是,启动时未安装默认的sigint处理程序,即在程序启动时,信号掩码包含
SIGIN
SIGIN
。可以找到对此负责的代码

被忽略信号的信号掩码从父进程继承,而处理的信号重置为
SIG_DFL
。因此,在忽略
SIGINT
的情况下,如果源代码中的(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
  • -i
    选项添加到shell脚本的shebang中,例如:

    #!/bin/sh -i
    

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

    信号

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


    这适用于非交互式Shell,因为默认情况下它们禁用了作业控制,实际上是在POSIX中指定的:

    感谢您的精彩解释。尽管如此,Python文档还是有点误导,不是吗?我认为它应该声明,如果在启动信号掩码中没有忽略SIGINT处理程序,它只会添加SIGINT处理程序。是的,文档可能应该提到,在startupExcellent上,它没有设置SIGINT处理程序,当它没有设置为
    SIG_DFL
    时,它没有设置SIGINT处理程序,这是我今天学习Python的第一件新事情。
    #!/bin/sh -i