一个需要在系统后台执行的脚本,为了防止被关闭,需要在后台定时检查是否在运行,定时检查使用任务计划实现。
实现这类功能有若干个办法,其中就有互锁方法,绑定一个特定端口socket等,这里用的是查找进行中运行脚本命令行的方式。
参考这篇文章实现http://www.cnblogs.com/hyb1/archive/2013/04/25/3042179.html
运行环境:python2.7 运行平台Windows7
使用中发现会存在两个实例在运行的问题,经过排查,问题的根本原因如下:
在命令行中执行 'wmic process where caption=python.exe get caption,commandline /value'
在重复运行时,会存在两种命令行格式,其中Python包含带引号和不带引号的两种方式
CommandLine="C:\Python27\python.exe" "C:\Users\Administrator\TestRun.py"
CommandLine=C:\Python27\python.exe "C:\Users\Administrator\TestRun.py"
故针对原文中的匹配的正则表达式
matchObj = re.compile(r"CommandLine=.+?"+processName[0]+r"['\"]{1}[\t ]*[\"']{1}(.*)[\"']{1}",re.I)
修改为
matchObj = re.compile(r"CommandLine=.+?"+processName[0]+r"['\"]?[\t ]*[\"']{1}(.*)[\"']{1}",re.I)
?号代表匹配前面字符串0或者1次,也可以用{0,1}更复杂一些,最后使用matchObj.findall可以提取出(.*)所代表的命令行字符串内容
def getProcessInfo(processName):
command ="tasklist | findstr \""+processName[0]+"\""
ret = os.system(command)
if ret != 0: #can't find it
#print processName[0]+" can't find it"
return False
原文中还有上面一段,判断python.exe是否在运行,认为没有必要,直接删掉,修改后参考代码如下:
def getProcessInfo(processName):
command = 'wmic process where caption="'+processName[0]+'" get caption,commandline /value'
pipe = os.popen(command)
pipeString = pipe.read()
pipe.close()
matchObj = re.compile(r"CommandLine=.+?"+processName[0]+r"['\"]?[\t ]*[\"']{1}(.+?)[\"']{1}",re.I)
list = matchObj.findall(pipeString)
number = 0
for i in list:
if i == processName[1]:
number=number+1
if number >= 2:
return True
else:
return False
if __name__ == '__main__':
print sys.argv[0]
if getProcessInfo(["python.exe",sys.argv[0]]) == True:
pass
if getProcessInfo(["pythonw.exe",sys.argv[0]]) == True:
pass