运行 后台进程挂起 PHP 页面
running process in background on hangs PHP page
我有一个启动 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
Nohup 似乎没有解决问题,因为它仍然重定向到标准输出。我在我的 linux 开发箱上确认了。
您需要做的是将输出重定向到 stdout/stderr:
shell_exec("sudo python /home/pi/Desktop/PiControl/motion_sensor.py >/dev/null 2>&1 &");
通过添加 >/dev/null
,您将输出定向到 /dev/null。通过使用 2>&1
,您将错误定向到与输出 (/dev/null) 相同的位置。如果需要,您也可以使用日志文件。如果要附加到文件,请将 >
更改为 >>
。
我有一个启动 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
Nohup 似乎没有解决问题,因为它仍然重定向到标准输出。我在我的 linux 开发箱上确认了。
您需要做的是将输出重定向到 stdout/stderr:
shell_exec("sudo python /home/pi/Desktop/PiControl/motion_sensor.py >/dev/null 2>&1 &");
通过添加 >/dev/null
,您将输出定向到 /dev/null。通过使用 2>&1
,您将错误定向到与输出 (/dev/null) 相同的位置。如果需要,您也可以使用日志文件。如果要附加到文件,请将 >
更改为 >>
。