【问题标题】:PHP not waiting for exec() to finish when I want it toPHP 不等待 exec() 在我想要的时候完成
【发布时间】:2015-11-30 21:09:17
【问题描述】:

我正在为 Raspberry Pi 上的数据记录工具运行 Web 界面。 PHP5.

用户按下一个按钮,该按钮调用一个 PHP 脚本来运行一个进程(使用 exec),然后返回结果文件。无论出于何种原因,exec() 函数都不会等待完成,并且脚本会失败,因为它要查找的文件尚未创建。

当我用一个简单的脚本替换脚本时,例如 print,等待 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() 应该等待您调用的任何内容完成。对某些脚本这样做,但对其他脚本则不然。

【问题讨论】:

  • 我怀疑您的 python 脚本由于某种原因从 php 启动时实际上无法正常运行。也许检查输出以找出如何/为什么。
  • sudo chown _www:_www /data/scripts/test.py

标签: php python raspberry-pi2


【解决方案1】:

Exec是一个同步阻塞调用,当没有&amp;传递给参数时强制程序/执行在后台发生。

这让我相信处理请求的Apache 实例的所有者没有执行Python 脚本的权限。

您应该相应地调整脚本或 Apache 用户的权限。

【讨论】:

  • 就是这样,脚本没有权限写入我希望它创建文件的目录。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
相关资源
最近更新 更多