2015-11-30 21 views
0

我正在運行Raspberry Pi上的數據記錄工具的Web界面。 PHP5。PHP不等待exec()完成,當我想要它

用戶按下一個按鈕,該按鈕調用PHP腳本來運行進程(使用exec),然後返回結果文件。無論出於何種原因,exec()函數都不會等待完成,並且腳本因其所查找的文件尚未創建而失敗。

當我用一個簡單的腳本(如打印)替換腳本時,等待5秒,打印 - 然後它確實等待exec()完成。唯一的區別是我調用的python腳本。有沒有人有任何洞察到什麼可能造成這種情況?

php腳本:

<?php 

    $file = "/var/tmp/logs/FaultLog.csv"; 

    exec("python /data/scripts/test.py", $output, $return); 

    if (!file_exists($file)) { 
     die ("Error: Fault log could not be created."); 
    } 

    $type = filetype($file); 
    // Send file headers 
    header("Content-type: $type"); 
    header("Content-Disposition: attachment;filename=FaultLog.csv"); 
    header("Content-Transfer-Encoding: binary"); 
    header('Pragma: no-cache'); 
    header('Expires: 0'); 
    // Send the file contents. 
    set_time_limit(0); 
    readfile($file); 
?> 

Python腳本工作:

import time 
print "hello" 
time.sleep(5) 
print "goodbye" 

Python腳本,不工作。這很長,但我決定將其全部納入以防萬一。

#!/usr/bin/env python 

import sqlite3, subprocess, re, os 

faultID = hours = minutes = 0 

csv_path = "/var/tmp/logs/" 
db_path = "/data/databases/FaultDictionary.db" 

def parse_msg (line): 

     global faultID, hours, minutes 

     if (" 12 41 01 " in line):      #single message 
       #parse CAN data 
       try: 
         data = line.split(" ")[4][12:17].replace(" ","") 
         faultID = int(data[2:] + data[:2], 16) 
       except: 
         return "Error: Unable to parse data. Data: " + line 

     elif (" 12 41 02 " in line):      #single message 
       #parse CAN data 
       try: 
         data = line.split(" ")[4][12:17].replace(" ","") 
         hours = int(data[2:] + data[:2], 16) 
       except: 
         return "Error: Unable to parse data. Data: " + line 

     elif (" 12 41 03 " in line):      #single message 
       #parse CAN data 
       try: 
         minutes = int(line.split(" ")[4][12:14], 16) 
       except: 
         return "Error: Unable to parse data. Data: " + line 

     elif ("581 [8] 80" in line):       #crashed 
       return "Error: Crashed motor controller. Please try again." 
     else: 
       return "Error: Unexpected message format, cannot decode reply from motor controller. Data: " + line 

     return "" 

conn = sqlite3.connect(db_path) 
curs = conn.cursor() 

#note time 
p = subprocess.Popen("date +\"%Y-%m-%d %H:%M\"", stdout=subprocess.PIPE, shell=True) 
(output, err) = p.communicate() 
current_date = output 

#Create needed folder structure 
if not (os.path.exists(csv_path)): 
     os.makedirs(csv_path) 

csv_path += "FaultLog.csv" 

with open(csv_path, 'w+') as file: 
     file.write("Date:," + current_date[:10] + "\n") 
     file.write("Time:," + current_date[11:] + "\n\n") 

     #SEVCON Fault Retreival 
     file.write('Hours Ago [h], Minutes & Seconds Ago, Fault ID, Fault Name, Fault Cause, Fault Remedy\n') 

     #send password to gain access 
     p = subprocess.Popen("cansend can0 601#2B005002DF4BEFFA", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
     p = subprocess.Popen("candump -t A -n 1 -T 100 can0,581:7ff", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
     (output, err) = p.communicate() 

     for num in range(0,40): 
       pass 

       #select event through 4111 
       p = subprocess.Popen("cansend can0 601#2B114100" + hex(num)[2:].zfill(2) + "00EFFA", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
       p = subprocess.Popen("candump -t A -n 1 -T 100 can0,581:7ff", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
       (output, err) = p.communicate() 

       #send request for event ID through 4112 
       p = subprocess.Popen("(sleep 0.1; cansend can0 601#4012410100000000; cansend can0 601#4012410200000000; cansend can0 601#4012410300000000;) &", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
       p = subprocess.Popen("candump -t A -n 3 -T 500 can0,581:7ff", cwd="/data/can-utils/", stdout=subprocess.PIPE, shell=True) 
       (output, err) = p.communicate() 

       message = "" 
       if len(output) > 0: # got the response message 

         lines = output.strip().split("\n") 

         for line in lines: 
           message = parse_msg(line) 

       else: 
         message = "Error: Did not receive reply from motor controller." 

       if message == "":  
         #query database for fault description and remedy 
         curs.execute("SELECT * FROM FaultDictionary WHERE faultID = '" + str(faultID) + "'") #faultID, message, description, action 
         for row in curs: #only ever one, since unique 
           #record to csv 
           file.write(str(hours) + "," + str(minutes) + "," + str(row[0]) + "," + str(row[1]) + "," + str(row[2]) + "," + str(row[3]) + "\n") 
           #print str(hours) + "," + str(minutes) + "," + str(row[0]) + "," + str(row[1]) + "," + str(row[2]) + "," + str(row[3]) + "\n" 
       else: 
         print message 
         break 

     #BMS Fault Retrieval 
     #file.write('\n\nFault ID\n') 

if not message == "": 
     os.remove(csv_path) 

conn.close() 

tldr; PHP exec()函數調用python腳本。 Exec()應該等待你要調用的任何東西來完成。對某些腳本是這樣,但不是其他腳本。

+0

我懷疑你的python腳本實際上無法運行,因爲它應該從PHP啓動出於某種原因。也許檢查輸出以找出如何/爲什麼。 – Calimero

+0

'sudo chown _www:_www/data/scripts/test.py' – Cyclonecode

回答

1

當沒有&傳遞給參數以強制程序/執行發生在後臺時,Exec是一個同步阻塞調用。

這使我相信處理請求的Apache實例的所有者沒有權限執行Python腳本。

您應該相應地調整腳本或Apache用戶的權限。

+1

就是這樣,腳本沒有權限寫入我希望創建文件的目錄。感謝您的幫助! – jules0075