2016-11-08 41 views
0

我在靠牆試圖讓我的代碼正常工作。實質上,我寫了一個將由cron調用的python腳本。該腳本每週運行一次以執行數據庫維護。我的python腳本將調用執行實際維護的perl腳本。我必須這樣構建它,因爲perl腳本將總共運行9次。有3個不同類別的數據庫項目,每個類別需要3個不同的來自Perl腳本的動作。如果任何類別的單個操作失敗,腳本將從該類別中斷開並轉到下一個操作(每個操作都取決於之前的操作)。將子進程管理到Linux中的一個文件中

我的腳本無法正常執行,我不知道爲什麼。我試圖解決它,但我的日誌邏輯不正常工作。我在我的日誌文件中獲得的唯一輸出是簡單的「打印」命令,我已經寫入腳本中進行記錄和格式化。

我可以直接從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() 
+0

它是如何失敗的?發生什麼事?有沒有輸出?你需要包含更多的細節。你可以[編輯]你的問題。你沒有自己寫Perl程序,是嗎?它要麼已經在那裏,要麼隨附你使用的任何軟件。 – simbabque

+0

'check_output'返回命令的輸出,但對於已經將其輸出寫入文件的命令來說沒有多大意義。你可以使用'subprocess.call'代替。 – chepner

+0

@simbabque - 感謝您的反饋。我添加了一些額外的細節來回答你的問題。 – Brian

回答

2
concatvar = "/usr/bin/perl -I /opt/voyence/tools/db-utility/common /opt/voyence/tools/db-utility/database-utility.pl" + CallLoad + " >> " + LOGFILE 

本小節將您的程序名稱(database-utility.pl)與CallLoad變量的內容進行比較 - 不要在它們之間放置空格。因此,除非CallLoad中的值以空格開頭,否則您實際上正在尋找名爲database-utility.plWhateverIsInCallLoad的程序。

+0

是的,我佔了間距。在動作中,每一個作爲呼叫加載傳遞的參數都在空格前面。 – Brian

+0

是的,我現在看到了。我知道這不會導致你的問題。但是,把這個空間放在我上面引用的路線(它的存在是否合理),而不是在每個單獨的論證中(它的存在是一個謎),不是更好嗎? –

+1

是的,我同意你的思考過程。你的改變很有意義。我想我現在會把它合併。 – Brian

0

未經測試,但更慣用的Python。主要更改是在調用Perl腳本時完全繞過外殼,並記錄可能由subprocess.call引發的任何錯誤以幫助調試問題。 (考慮使用logging模塊代替,但已經有足夠的變化。)

#! /usr/bin/python 
import sys 
import time 
import os 
import subprocess 

def subprocess_caller(path, call_load, log_obj): 
    subprocess.call(["/usr/bin/perl", 
        "-I", 
        "/opt/voyence/tools/db-utility/common", 
        path, 
        call_load], 
        stdout=log_obj) 

log_header = """\ 
------------------------------------------------------------------------------------------------------ 
Weekly Voyence archival, deletion, and purging of jobs, events, and revisions beginning at %s 
""" %(time.strftime("%H:%M:%S"),) 

if __name__ == "__main__": 

    #declare variables and objects 
    path = "/opt/voyence/tools/db-utility/database-utility.pl" 
    logfile = time.strftime("/var/log/voyence-archive/%Y%m%dvoyence-archive.log") 

    #create new log file 
    with open(logfile, "a+") as log: 
     log.write(hog_header) 
     #job archival, deletion, and purging 
     job_actions = [" archive jobs 90"," delete jobs 90"," purge jobs 275"] 
     #event archival, deletion, and purging 
     event_actions = [" archive events all 90"," delete events all 90"," purge events all 275"] 
     #revision archival, deletion, and purging 
     revision_actions = [" archive revisions 40"," purge revisions 60"," delete revisions '3 months' 40"] 

     actions = job_actions + event_actions + revision_action: 

     for action_type in actions: 
      for item in action_type: 
       try: 
        subprocess_caller(path, item, log) 
       except Exception as exc: 
        log_obj.write(exc + "\n") 
        log_obj.write("Block failed, continuing to next block\n") 
        break 
       log.write("------\n") 

     log.write("Weekly Voyence archival, deletion, and purging of jobs, events, and revisions complete at %s\n" % 
        (time.strftime("%H:%M:%S"),)) 
+0

感謝您的原型。我在我身邊做了一些改變,以糾正出現的一些錯誤。我已經知道我的開發箱上有一個可行的腳本,我會讓它在今晚運行爲cron作業,以查看它的行爲。我會讓你知道結果如何。 – Brian