在 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
Simulate Ctrl-C keyboard interrupt in Python while working in Linux
提问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.Popen
to 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 buff
file descriptor opened in read+write mode. I check the last line; if it has 'done'
, I kill it. Unfortunately, the CTRL_C_EVENT
is 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 buff
is, you query it first, then use it in the context of Popen()
and then you hope that by maciv lineList
fills 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 vprobe
script 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() 来阻止命令..