开发者

sending keyboard interrupt programmatically

开发者 https://www.devze.com 2023-04-10 02:24 出处:网络
An application that asks for a keyboard interrupt. How can I send for a keyboard interrupt programmatically? I need it for automation.

An application that asks for a keyboard interrupt. How can I send for a keyboard interrupt programmatically? I need it for automation. Like <C-c> or <C-x>

Key开发者_运维问答boardInterrupt 


Code running in a separate thread can cause a KeyboardInterrupt to be generated in the main thread by calling thread.interrupt_main(). See https://docs.python.org/2/library/thread.html#thread.interrupt_main


Since you mention automation I assume you want a SendKeys for Python. Try this: http://rutherfurd.net/python/sendkeys/


My suggestion to solve this problem is to use the following code pattern. I used it to programmatically start a tensorboard server and shut it down by sending a CTRL-C when the object it belongs to is deleted. Generally speaking, this should work for any example that provokes a subprocess that is supposed to be send a KeyBoardInterrupt:

  1. Import signal and subprocess

    import signal
    import subprocess 
    
  2. Create the subprocess using subprocess.Popen. Important: set the creationflags parameter to subprocess.CREATE_NEW_PROCESS_GROUP. This is necessary to later be able to send the KeyboardInterrupt event.

    command= <enter your command that is supposed to be run in different process as a string> 
    process = subprocess.Popen(command.split(),stdout=subprocess.PIPE,stdin=subprocess.PIPE,creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) 
    
  3. Wherever you want to send the keyboardInterrupt, do the following:

    process.send_signal(signal.CTRL_C_EVENT)
    

That is it! Please see the the official subprocess documentation for insights on why the creationflags parameter of popen has to be set that way.


This is how the code looks for my example in a less generic way:

import signal
import subprocess
import time

class ExperimentTracker():
   
     def __init__(self):
         self.tensorboard_process=None

     def __del__(self):
         #shutdown tensorboard server and terminate process
         self.tensorboard_process.send_signal(signal.CTRL_C_EVENT)
         time.sleep(0.2)
         self.tensorboard_process.kill()

     def launch_tensorboard(self):
         #launch tensorboard
         bashCommand= "tensorboard --logdir runs" 
         self.tensorboard_process = subprocess.Popen(bashCommand.split(),stdout=subprocess.PIPE,stdin=subprocess.PIPE,creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) 
         time.sleep(2) #sleep for 2 seconds to give tensorboard time to be launched
         


If say you want to run a program via shell ./program. In Linux what you could do is:

# Made a function to handle more complex programs which require multiple inputs.
run(){
    ./program
}

# Making a child process that will run the program while you stop it later.
run & 
childPid=($!)
# Process id of the program which you want to interrupt (via `run`).

# Time after which you want to interrupt
sleep 5

# Actual command to send the interrupt
kill -SIGINT $childPid

Let me know if it works in windows as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消