【问题标题】:running process in background on hangs PHP page在后台运行进程挂起 PHP 页面
【发布时间】:2015-04-26 17:47:49
【问题描述】:

我有一个启动 python 脚本的 PHP 页面,但 PHP 页面挂起直到脚本完成。有没有办法运行不会让它挂起的脚本?

PHP 代码

在alarm_on的情况下会出现问题。所有其他情况都可以正常工作。

<?php
session_start();
if(isset($_COOKIE['userME']))
    echo "Hello, ".$_COOKIE['userME'].'<br>';

if(isset($_SESSION['UserData']['Username']) || $passed )// or $logins[$Username] == $Password)
{
if (isset($_POST['submit'])) {
    switch ($_POST['submit']) {
        case 'room_light':
                 echo shell_exec("sudo python /home/pi/Desktop/PiControl/room_light.py");
                break;
        case 'alarm_on':
                echo "alarm started";
                shell_exec("nohup sudo python /home/pi/Desktop/PiControl/motion_sensor.py &");
                echo "alarm on";
                break;
        case 'alarm_off':
                echo "alarm off"; 
                echo shell_exec("sudo pkill -f motion_sensor.py");
                break;
}
}
?>

<form method="post">
<input type="submit" name="submit" value="room_light">
<input type="submit" name="submit" value="alarm_on">
<input type="submit" name="submit" value="alarm_off">
</form>
<?php
}
else
{
    header("location:login.php");
}
?>

motion_sensor.py

import sys
import urllib2, urllib
import RPi.GPIO as GPIO
#setup GPIO using Board numbering. pin physical number corresponds to gpio call
GPIO.setmode(GPIO.BOARD)

pin=37
url="http://MY_IP/test.php"

GPIO.setup(pin, GPIO.IN)

def alarmChange(channel):
    if(GPIO.input(pin)):
        print 'Sensor tripped',channel
        postdata={'sensor_tripped': channel}
        postdata=urllib.urlencode(postdata)
        req=urllib2.Request(url, postdata)
        req.add_header("Content-type", "application/x-www-form-urlencoded")
        page=urllib2.urlopen(req).read()
        #print page
    else:
        print 'sensor no longer tripped', channel

GPIO.add_event_detect(pin, GPIO.BOTH, callback=alarmChange)
print "alarm on"
while True: #this is a hack to keep the script running all the time so it will continue event detection
    i=0

GPIO.cleanup() #should never hit this point

【问题讨论】:

  • 注意shell_execphp.net/manual/en/function.shell-exec.php 的含义是将完整的输出作为字符串返回。如果你想让一个命令在后台运行,那自然会与想要在它发生时读取它的输出相冲突。

标签: php python linux background-process


【解决方案1】:

Nohup 似乎没有解决问题,因为它仍然重定向到标准输出。我在我的 linux 开发盒上确认了。

您需要做的是将输出从 stdout/stderr 重定向:

shell_exec("sudo python /home/pi/Desktop/PiControl/motion_sensor.py >/dev/null 2>&1 &");

通过添加&gt;/dev/null,您将输出定向到/dev/null。通过使用2&gt;&amp;1,您将错误定向到与输出相同的位置(/dev/null)。如果需要,您也可以使用日志文件。如果要追加到文件,请将&gt; 更改为&gt;&gt;

【讨论】:

  • 尝试 nohup 后,我仍然遇到同样的问题。我更新了我的帖子以包含整个 PHP 页面,以防万一。谢谢!
  • @Rilcon42,是的,看起来 nohup 没有重定向输出,导致它仍然被锁定。我已经更新了我的答案,向您展示如何重定向输出。
  • 此次更新让一切都运行良好。谢谢!
猜你喜欢
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 2011-07-14
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多