简体   繁体   English

使用浏览器在 php 脚本中调用时,Raspberry Pi Python 代码无法正确执行

[英]Raspberry Pi Python code not executing properly when called in php script using a browser

I have a Raspberry Pi 1B running Raspbian 10 (buster) with Python3, Apache2 and PHP installed, and rigged up with a strip of WS2812 LEDs.我有一个运行 Raspbian 10 (buster) 的 Raspberry Pi 1B,安装了 Python3、Apache2 和 PHP,并安装了一条 WS2812 LED。

I have a simple Python script (PixelTestOn.py, see below) that turns all the LEDs on.我有一个简单的 Python 脚本(PixelTestOn.py,见下文)可以打开所有 LED。 When using the following Terminal command, the LEDs all light up and the text within the script is displayed as expected:使用以下终端命令时,LED 全部亮起,脚本中的文本按预期显示:

sudo python3 PixelTestOn.py*

PixelTestOn.py PixelTestOn.py

#! /usr/bin/env python3

print("PixelTestOn started<br>")

from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 30        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 40   # Set to 0 for darkest and 255 for brightest
LED_INVERT = True     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create NeoPixel object with appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Intialize the library (must be called once before other functions).
strip.begin()

# Switch all pixels on
for i in range(strip.numPixels()):
    strip.setPixelColor(i, Color(255, 255, 255))
strip.show()

print("PixelTestOn finished")

exit()

I also have a php script (PixelTestOn.php, see below) that should display some text, execute the PixelTestOn.py python script to turn on the LEDs, then display some more text.我还有一个 php 脚本(PixelTestOn.php,见下文),它应该显示一些文本,执行 PixelTestOn.py python 脚本来打开 LED,然后显示更多的文本。 When using the following Terminal command, the HTML code is displayed, and the LEDs all light up and the text within the python script is displayed, all as expected:使用以下终端命令时,将显示 HTML 代码,并且 LED 全部亮起,并显示 python 脚本中的文本,一切如预期:

sudo php PixelTestOn.php

PixelTestOn.php PixelTestOn.php

<html>
<head>
<title>Pixel Test</title>

<h3>Test to turn LEDs on</h3>
<p>Should see all LEDs light up</p>
<p></p>
<p>About to call shell_exec() (5)</p>

<?PHP
echo shell_exec("python PixelTestOn.py");
?>

<p>Returned from shell_exec()</p>

</head>

However, when I enter the following into the Chromium browser the html output (not code) is displayed and the text in the first print() statement at the start of the python code is displayed as expected, however, the LEDs do not light up and the text in the second print() statement at the end the python code is not displayed:但是,当我在 Chromium 浏览器中输入以下内容时,将显示 html 输出(不是代码),并且 Python 代码开头的第一个 print() 语句中的文本按预期显示,但是,LED 不亮并且不显示python代码末尾的第二个print()语句中的文本:

localhost/PixelTestOn.php

If I comment out all the statements between the 2 print() statements then the script is executed as expected in the browser.如果我注释掉 2 个 print() 语句之间的所有语句,则脚本将在浏览器中按预期执行。

All the files are stored in the /var/www/html directory, all have the owner www-data, and all have the access controls set to 'Anyone'.所有文件都存储在 /var/www/html 目录中,所有文件的所有者都是 www-data,并且都将访问控制设置为“任何人”。

Here's what I've tried:这是我尝试过的:

  • Using shell_exec(), exec() and system() in the php script在 php 脚本中使用 shell_exec()、exec() 和 system()
  • Using different browsers (Echo, IE, Chrome) on my Windows 10 PC and Chrome on an Android tablet.在我的 Windows 10 PC 和 Android 平板电脑上使用不同的浏览器(Echo、IE、Chrome)。 Note that SSH is enabled on the Pi.请注意,在 Pi 上启用了 SSH。
  • Two different LED control libraries, rpi_ws281x and neopixel两个不同的 LED 控制库,rpi_ws281x 和 neopixel
  • The Common Gateway Interface (CGI).通用网关接口 (CGI)。 I couldn't get this to work with an html based form with a [Submit] button, when the button was pressed to enter the data an 'Internal Server Error' message was displayed in the browser.我无法使用带有 [提交] 按钮的基于 html 的表单来使用它,当按下按钮输入数据时,浏览器中会显示“内部服务器错误”消息。

My ultimate intention is to build an electronic cricket scoreboard based on a headless Raspberry Pi with individually addressable LEDs, that is accessed remotely via an Android tablet.我的最终目的是构建一个基于无头 Raspberry Pi 的电子板球记分牌,带有可单独寻址的 LED,可通过 Android 平板电脑远程访问。

Update Following Jay's comment I tried running 'python3 PixelTestOn.py' ie without 'sudo' in Terminal and got the following error message after the print statement 'PixelTestOn started更新按照 Jay 的评论,我尝试在终端中运行“python3 PixelTestOn.py”即没有“sudo”,并在打印语句“PixelTestOn 启动”后收到以下错误消息
' was displayed: ' 显示:

Can’t open /dev/mem: Permission denied
Traceback (most recent call last):
  File “PixelTestOn.py”, line 24, in <module>
    strip.begin()
  File “/home/pi/.local/lib/python3.7/site-packages/rpi_ws281x/rpi_ws281x.py”, line 130, in begin
    raise RuntimeError(‘ws2811_init failed with code {0} ({1})’.format(resp, str_resp))
RuntimeError: ws2811_init failed with code -5 (mmap() failed)

Seeing the 'Permission denied' statement I made a note of the permissions on file '/dev/mem' then entered the following to change the access control to 'Anyone' for all 3 options.看到“权限被拒绝”语句,我记下了文件“/dev/mem”的权限,然后输入以下内容将所有 3 个选项的访问控制更改为“任何人”。

sudo 777 /dev/mem

I then re-ran 'python3 PixelTestOn.py' in Terminal and, again after the print statement 'PixelTestOn started然后我在终端中重新运行 'python3 PixelTestOn.py',再次在打印语句 'PixelTestOn 开始后
' was displayed, got a similar error message but this time starting with: ' 显示,收到类似的错误消息,但这次从:

Can’t open /dev/mem: Operation not permitted

I then changed the permissions on /dev/mem back to their original settings然后我将 /dev/mem 的权限改回原来的设置

Welcome to Stack-overflow.欢迎使用堆栈溢出。

According to below link, I see that you cannot avoid running the python script as root - https://github.com/jgarff/rpi_ws281x/issues/155#issuecomment-370939228根据以下链接,我看到您无法避免以 root 身份运行 python 脚本 - https://github.com/jgarff/rpi_ws281x/issues/155#issuecomment-370939228

So you need to do below, for sure -所以你需要在下面做,当然 -

echo shell_exec("sudo python PixelTestOn.py"); # Note the 'sudo' prefix

Also, when you run PHP via a browser, like Chromium or Firefox etc, the request has to travel through your web-server (Apache, NginX etc).此外,当您通过浏览器(如 Chromium 或 Firefox 等)运行 PHP 时,请求必须通过您的网络服务器(Apache、NginX 等)。 Hence, your PHP script will be executed as a web user and not root.因此,您的 PHP 脚本将以 Web 用户而非 root 用户身份执行。

Assuming, by your question, that your web user is www-data , please add below text in your /etc/sudoers file to allow www-data to run commands as sudo -假设,根据您的问题,您的网络用户是www-data ,请在您的/etc/sudoers文件中添加以下文本,以允许www-data以 sudo 身份运行命令 -

www-data ALL=(ALL) NOPASSWD: ALL

This should solve your issue.这应该可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM