Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

linux

kill

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

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:

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?

like image 604
Core_Dumped Avatar asked Oct 23 '12 06:10

Core_Dumped


2 Answers

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

(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.)

like image 165
Andrew Gorcester Avatar answered Sep 22 '22 19:09

Andrew Gorcester


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.

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.

like image 38
glglgl Avatar answered Sep 21 '22 19:09

glglgl