我有一个Python脚本,每60秒运行一整天的检查时间,因此它可以在一天中的特定时段开始/结束任务(其他python脚本)。
这个脚本几乎都运行正常。任务在正确的时间开始,并在新的cmd
窗口上打开,因此主脚本可以继续运行并对时间进行采样。唯一的问题是它不会杀死任务。
import os
import time
import signal
import subprocess
import ctypes
freq = 60 # sampling frequency in seconds
while True:
print 'Sampling time...'
now = int(time.time())
#initialize the task.. lets say 8:30am
if ( time.strftime("%H:%M", time.localtime(now)) == '08:30'):
# The following method is used so python opens another cmd window and keeps original script running and sampling time
pro = subprocess.Popen(["start", "cmd", "/k", "python python-task.py"], shell=True)
# kill process attempts.. lets say 11:40am
if ( time.strftime("%H:%M", time.localtime(now)) == '11:40'):
pro.kill() #not working - nothing happens
pro.terminate() #not working - nothing happens
os.kill(pro.pid, signal.SIGINT) #not working - windows error 5 access denied
# Kill the process using ctypes - not working - nothing happens
ctypes.windll.kernel32.TerminateProcess(int(pro._handle), -1)
# Kill process using windows taskkill - nothing happens
os.popen('TASKKILL /PID '+str(pro.pid)+' /F')
time.sleep(freq)
重要提示:任务脚本python-task.py
将无限期运行。这正是为什么我需要在它仍在运行的某个时间“强制”杀死它的原因。
任何线索?我究竟做错了什么?如何杀死它?
答案 0 :(得分:1)
您正在杀死产生子流程的shell,而不是您的子流程。
编辑:来自文档:
您需要在Windows上指定shell = True的唯一时间是您希望执行的命令是否内置到shell中(例如dir或copy)。您不需要shell = True来运行批处理文件或基于控制台的可执行文件。
警告
如果与不受信任的输入结合使用,则传递shell = True可能会造成安全隐患。有关详细信息,请参阅“常用参数”下的警告。
因此,不是传递单个字符串,而是在列表中单独传递每个参数,并使用shell避开。您可能希望为子项使用与父项相同的可执行文件,因此它通常类似于:
pro = subprocess.Popen([sys.executable, "python-task.py"])