Имитация прерывания клавиатуры Ctrl-C в Python при работе в Linux
Я работаю над некоторыми сценариями (в компании, в которой я работаю), которые загружаются/выгружаются в гипервизоры для запуска фрагмента кода при возникновении события. Единственный способ фактически выгрузить скрипт-это нажать Ctrl-C. Я пишу функцию в Python, которая автоматизирует процесс
как только он видит строку "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 вы можете видеть, я пишу вывод в buff файловый дескриптор открыт в режиме чтения+записи. Я проверяю последнюю строку; если она имеет 'done', Я убью его. К сожалению,CTRL_C_EVENT действует только для Windows.
Что я могу сделать для Linux?
3 ответов
Я думаю, вы можете просто отправить эквивалент Linux,signal.SIGINT (сигнал прерывания).
(Edit: раньше у меня было что-то, препятствующее использованию этой стратегии для управления подпроцессами, но при более тщательном чтении это звучит так, как будто вы уже решили, что вам нужен control-C в этом конкретном случае... Итак, SIGINT должен это сделать.)
в Linux прерывание клавиатуры Ctrl-C может быть отправлено программно процессу с помощью Popen.send_signal(сигнал.SIGINT) функция. Например
import subprocess
import signal
..
process = subprocess.Popen(..)
..
process.send_signal(signal.SIGINT)
..
Не используйте Popen.communicate () для блокировки команд..
может быть, я что-то неправильно понял, но так, как вы это делаете, трудно получить желаемый результат.
все buff есть запросы, а затем использовать его в контексте Popen() и тогда вы надеетесь, что maciv lineList заполняется.
что вы, вероятно, хотите что-то вроде
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)
это дает вам конец трубы, питаемый вашим vprobe скрипт, который вы можете прочитать линейно и действовать соответствующим образом на найденном выходе.