【发布时间】:2017-03-22 06:32:11
【问题描述】:
我正在努力让我的代码正常工作。本质上,我编写了一个将由 cron 调用的 python 脚本。该脚本每周运行一次以执行数据库维护。我的 python 脚本将调用执行实际维护的 perl 脚本。我不得不以这种方式构建它,因为 perl 脚本将总共运行 9 次。有 3 个不同类别的 DB 项,每个类别需要来自 perl 脚本的 3 个不同操作。如果任何类别中的单个操作失败,脚本将从该类别中断并移至下一个(每个操作都依赖于前一个操作)。
我的脚本无法正确执行,我不知道为什么。我正在尝试对其进行故障排除,但我的日志记录逻辑也无法正常工作。我在日志文件中得到的唯一输出是简单的“打印”命令,这些命令是我写到脚本中用于表示和格式化的。
我可以直接从 CLI 很好地运行 perl 脚本,但是从我的 python 脚本调用时它无法正确运行。谁能指出我正确的方向吗?
编辑: 在回答一个问题时,我没有很好地解释 perl 脚本是如何失败的。我没有从 perl 脚本中获取 stdout 或 stderr 到我的日志文件中,所以我还不知道它为什么会失败。 我没有创建 perl 脚本,它是由我管理的软件套件提供的。
这是日志文件输出:
------------------------------------------------------------------------------------------------------
Weekly Voyence archival, deletion, and purging of jobs, events, and revisions beginning at 14:46:11
Block failed, continuing to next block
------
Block failed, continuing to next block
------
Block failed, continuing to next block
------
Weekly Voyence archival, deletion, and purging of jobs, events, and revisions complete at 14:46:11
这是从 CLI 运行 perl 脚本的输出(没有错误):
Script started at Mon Nov 7 14:59:53 2016
Archving/Pruning 0 Parent jobs older than 90 days...
Archving/Pruning 0 Child Jobs older than 90 days...
No Records avaialble for archive..jobs Exiting
Script Completed.
The database utility console log can be found at /opt/voyence/tools/db- utility/logs/dbutil_console.log
Script exited at Mon Nov 7 14:59:58 2016
这里是python脚本:
#! /usr/bin/python
import sys
import time
import os
import subprocess
def SubProcessCaller(PATH,CallLoad,LogObj,LOGFILE):
try:
# subprocess.Popen(["/usr/bin/perl", "-i", "/opt/voyence/tools/db- utility/database-utility.pl", CallLoad], stderr=LogObj.write, stdout=LogObj.write, shell=true)
concatvar = "/usr/bin/perl -I /opt/voyence/tools/db-utility/common /opt/voyence/tools/db-utility/database-utility.pl" + CallLoad + " >> " + LOGFILE
subprocess.check_output(concatvar.split(), shell=True)
return True
except:
LogObj.write("Block failed, continuing to next block" "\n")
return False
if __name__ == "__main__":
#DECLARE VARIABLES AND OBJECTS
TIME = time.strftime("%H:%M:%S")
PATH = "/opt/voyence/tools/db-utility/database-utility.pl"
DATE = time.strftime("%Y%m%d")
LOGFILE = "/var/log/voyence-archive/" + DATE + "voyence-archive.log"
LOG = open(LOGFILE, "a+")
#CREATE NEW LOG FILE
LOG.write("------------------------------------------------------------------------------------------------------\n")
LOG.write("Weekly Voyence archival, deletion, and purging of jobs, events, and revisions beginning at " + TIME + "\n")
#JOB ARCHIVAL, DELETION, AND PURGING
JobActionsDict = [" archive jobs 90"," delete jobs 90"," purge jobs 275"]
#EVENT ARCHIVAL, DELETION, AND PURGING
EventActionsDict = [" archive events all 90"," delete events all 90"," purge events all 275"]
#REVISION ARCHIVAL, DELETION, AND PURGING
RevisionActionsDict = [" archive revisions 40"," purge revisions 60"," delete revisions '3 months' 40"]
ActionsTuple = (JobActionsDict, EventActionsDict, RevisionActionsDict)
for dict in ActionsTuple:
for item in dict:
SPCBool = SubProcessCaller(PATH,item,LOG,LOGFILE)
if SPCBool == False:
break
LOG.write("------\n")
#CLOSE AFTER ALL LOGS HAVE BEEN WRITTEN
LOG.write("Weekly Voyence archival, deletion, and purging of jobs, events, and revisions complete at " + TIME + "\n")
LOG.close()
【问题讨论】:
-
它是怎么失败的?怎么了?有输出吗?您需要包含更多详细信息。你可以edit你的问题。 Perl 程序不是您自己编写的,是吗?它要么已经存在,要么随您使用的任何软件一起提供。
-
check_output返回命令的输出,但这对于已经将其输出写入文件的命令没有多大意义。你可以改用subprocess.call。 -
@simbabque - 感谢您的反馈。我添加了一些额外的细节来回答你的问题。
-
@chepner - 我最初使用了 subprocess.call ,我以为我已经将其注释掉了,但显然我将它从脚本中删除了。 .call 的结果与我从 .check_output 得到的结果相同
-
另外,不要捕获一个裸异常或忽略实际异常。使用
except Exception as exc:,然后至少将异常写入日志文件(或直接写入标准错误),以便查看实际问题。