gpt4 book ai didi

python - 使用子进程时处理键盘中断

转载 作者:太空狗 更新时间:2023-10-29 21:29:04 24 4
gpt4 key购买 nike

我有一个名为 monitiq_install.py 的 python 脚本,它使用 subprocess python 模块调用其他脚本(或模块)。但是,如果用户发送键盘中断 (CTRL + C),它会退出,但会出现异常。我希望它退出,但很好。

我的代码:

import os
import sys
from os import listdir
from os.path import isfile, join
from subprocess import Popen, PIPE
import json

# Run a module and capture output and exit code
def runModule(module):
try:
# Run Module
process = Popen(os.path.dirname(os.path.realpath(__file__)) + "/modules/" + module, shell=True, stdout=PIPE, bufsize=1)
for line in iter(process.stdout.readline, b''):
print line,

process.communicate()
exit_code = process.wait();

return exit_code;
except KeyboardInterrupt:
print "Got keyboard interupt!";
sys.exit(0);

我得到的错误如下:

python monitiq_install.py -a
Invalid module filename: create_db_user_v0_0_0.pyc
Not Running Module: '3parssh_install' as it is already installed
######################################
Running Module: 'create_db_user' Version: '0.0.3'
Choose username for Monitiq DB User [MONITIQ]
^CTraceback (most recent call last):
File "/opt/monitiq-universal/install/modules/create_db_user-v0_0_3.py", line 132, in <module>
inputVal = raw_input("");
Traceback (most recent call last):
File "monitiq_install.py", line 40, in <module>
KeyboardInterrupt
module_install.runModules();
File "/opt/monitiq-universal/install/module_install.py", line 86, in runModules
exit_code = runModule(module);
File "/opt/monitiq-universal/install/module_install.py", line 19, in runModule
for line in iter(process.stdout.readline, b''):
KeyboardInterrupt

解决方案或一些指示会有所帮助:)

--编辑用try catch

Running Module: 'create_db_user' Version: '0.0.0'
Choose username for Monitiq DB User [MONITIQ]
^CGot keyboard interupt!
Traceback (most recent call last):
File "monitiq_install.py", line 36, in <module>
module_install.runModules();
File "/opt/monitiq-universal/install/module_install.py", line 90, in runModules
exit_code = runModule(module);
File "/opt/monitiq-universal/install/module_install.py", line 29, in runModule
sys.exit(0);
NameError: global name 'sys' is not defined
Traceback (most recent call last):
File "/opt/monitiq-universal/install/modules/create_db_user-v0_0_0.py", line 132, in <module>
inputVal = raw_input("");
KeyboardInterrupt

最佳答案

如果您在终端中按下 Ctrl + C,那么 SIGINT 将发送到进程组中的所有进程。参见 child process receives parent's SIGINT .

这就是为什么尽管父进程中有 try/except KeyboardInterrupt,您仍会看到子进程的回溯。

您可以抑制子进程的 stderr 输出:stderr=DEVNULL。或者在一个新的进程组中启动它:start_new_session=True:

import sys
from subprocess import call

try:
call([sys.executable, 'child.py'], start_new_session=True)
except KeyboardInterrupt:
print('Ctrl C')
else:
print('no exception')

如果您在上面的示例中删除了 start_new_session=True,那么 KeyboardInterrupt 也可能在子级中引发,您可能会得到回溯。

如果 subprocess.DEVNULL 不可用;你可以使用 DEVNULL = open(os.devnull, 'r+b', 0)。如果 start_new_session 参数不可用;您可以在 POSIX 上使用 preexec_fn=os.setsid

关于python - 使用子进程时处理键盘中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23826695/

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