在 Linux 中工作时在 Python 中模拟 Ctrl-C 键盘中断

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13024532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:34:50  来源:igfitidea点击:

Simulate Ctrl-C keyboard interrupt in Python while working in Linux

pythonlinuxkill

提问by Core_Dumped

I am working on some scripts (in the company I work in) that are loaded/unloaded into hypervisors to fire a piece of code when an event occurs. The only way to actually unload a script is to hit Ctrl-C. I am writing a function in Python that automates the process

我正在处理一些脚本(在我工作的公司中),这些脚本被加载/卸载到管理程序中以在事件发生时触发一段代码。实际卸载脚本的唯一方法是点击Ctrl- C。我正在用 Python 编写一个函数来自动化这个过程

As soon as it sees the string "done"in the output of the program, it should kill the vprobe. I am using subprocess.Popento execute the command:

一旦它"done"在程序的输出中看到字符串,它就应该杀死vprobe. 我subprocess.Popen用来执行命令:

lineList = buff.readlines()
cmd = "vprobe /vprobe/myhello.emt"
p = subprocess.Popen(args = cmd, shell=True,stdout = buff, universal_newlines = True,preexec_fn=os.setsid)
while not re.search("done",lineList[-1]):
        print "waiting"
os.kill(p.pid,signal.CTRL_C_EVENT)

As you can see, I am writing the output in bufffile descriptor opened in read+write mode. I check the last line; if it has 'done', I kill it. Unfortunately, the CTRL_C_EVENTis only valid for Windows. What can I do for Linux?

如您所见,我在buff以读写模式打开的文件描述符中写入输出。我检查了最后一行;如果有'done',我杀了它。不幸的CTRL_C_EVENT是,仅对 Windows 有效。我能为 Linux 做什么?

采纳答案by Andrew Gorcester

I think you can just send the Linux equivalent, signal.SIGINT(the interrupt signal).

我认为您可以发送 Linux 等效项signal.SIGINT(中断信号)。

(Edit: I used to have something here discouraging the use of this strategy for controlling subprocesses, but on more careful reading it sounds like you've already decided you need control-C in this specific case... So, SIGINT should do it.)

(编辑:我曾经在这里不鼓励使用此策略来控制子进程,但仔细阅读后,听起来您已经决定在这种特定情况下需要 control-C ......所以,SIGINT 应该这样做.)

回答by glglgl

Maybe I misunderstand something, but the way you do it it is difficult to get the desired result.

也许我误解了一些东西,但是你这样做的方式很难得到想要的结果。

Whatever buffis, you query it first, then use it in the context of Popen()and then you hope that by maciv lineListfills itself up.

不管buff是什么,你先查询它,然后在上下文中使用它Popen(),然后你希望通过 macivlineList填满它自己。

What you probably want is something like

你可能想要的是

logfile = open("mylogfile", "a")
p = subprocess.Popen(['vprobe', '/vprobe/myhello.emt'], stdout=subprocess.PIPE,  buff, universal_newlines=True, preexec_fn=os.setsid)
for line in p.stdout:
    logfile.write(line)
    if re.search("done", line):
        break
    print "waiting"
os.kill(p.pid, signal.CTRL_C_EVENT)

This gives you a pipe end fed by your vprobescript which you can read out linewise and act appropriately upon the found output.

这为您提供了一个由vprobe脚本提供的管道末端,您可以逐行读出并根据找到的输出采取适当的行动。

回答by Asif Hasnain

In Linux, Ctrl-C keyboard interrupt can be sent programmatically to a process using Popen.send_signal(signal.SIGINT) function. For example

在 Linux 中,可以使用 Popen.send_signal(signal.SIGINT) 函数以编程方式将 Ctrl-C 键盘中断发送到进程。例如

import subprocess
import signal

..
process = subprocess.Popen(..)
..
process.send_signal(signal.SIGINT)
..

Don't use Popen.communicate() for blocking commands..

不要使用 Popen.communicate() 来阻止命令..