Имитация прерывания клавиатуры 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
скрипт, который вы можете прочитать линейно и действовать соответствующим образом на найденном выходе.