Запустите скрипт Python с переполнением стека

У меня есть этот файл Python:

light.py:

#!/usr/bin/python

import sys
import smbus
import time
from Adafruit_I2C import Adafruit_I2Cclass Luxmeter:
i2c = None

def __init__(self, address=0x39, debug=0, pause=0.8):
self.i2c = Adafruit_I2C(address)
self.address = address
self.pause = pause
self.debug = debug
self.gain = 0 # no gain preselected
self.i2c.write8(0x80, 0x03)     # enable the devicedef setGain(self,gain=1):
""" Set the gain """if (gain != self.gain):
if (gain==1):
self.i2c.write8(0x81, 0x02)     # set gain = 1X and timing = 402 mSec
if (self.debug):
print "Setting low gain"else:
self.i2c.write8(0x81, 0x12)     # set gain = 16X and timing = 402 mSec
if (self.debug):
print "Setting high gain"self.gain=gain;                     # safe gain for calculation
time.sleep(self.pause)              # pause for integration (self.pause must be bigger than integration time)def readWord(self, reg):
"""Reads a word from the I2C device"""try:
wordval = self.i2c.readU16(reg)
newval = self.i2c.reverseByteOrder(wordval)
if (self.debug):
print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, wordval & 0xFFFF, reg))
return newval
except IOError:
print("Error accessing 0x%02X: Check your I2C address" % self.address)
return -1def readFull(self, reg=0x8C):
"""Reads visible+IR diode from the I2C device"""return self.readWord(reg);

def readIR(self, reg=0x8E):
"""Reads IR only diode from the I2C device"""return self.readWord(reg);

def getLux(self, gain = 0):
"""Grabs a lux reading either with autoranging (gain=0) or with a specified gain (1, 16)"""if (gain == 1 or gain == 16):
self.setGain(gain) # low/highGain
ambient = self.readFull()
IR = self.readIR()
elif (gain==0): # auto gain
self.setGain(16) # first try highGain
ambient = self.readFull()
if (ambient < 65535):
IR = self.readIR()
if (ambient >= 65535 or IR >= 65535): # value(s) exeed(s) datarange
self.setGain(1) # set lowGain
ambient = self.readFull()
IR = self.readIR()

if (self.gain==1):
ambient *= 16    # scale 1x to 16x
IR *= 16         # scale 1x to 16x

if (float(ambient) != 0):
ratio = (IR / float(ambient)) # changed to make it run under python 2
else: ratio = 0

if (self.debug):
print "IR Result", IR
print "Ambient Result", ambient

if ((ratio >= 0) & (ratio <= 0.52)):
lux = (0.0315 * ambient) - (0.0593 * ambient * (ratio**1.4))
elif (ratio <= 0.65):
lux = (0.0229 * ambient) - (0.0291 * IR)
elif (ratio <= 0.80):
lux = (0.0157 * ambient) - (0.018 * IR)
elif (ratio <= 1.3):
lux = (0.00338 * ambient) - (0.0026 * IR)
elif (ratio > 1.3):
lux = 0

return luxoLuxmeter=Luxmeter()

i=0
while True:
light = oLuxmeter.getLux(1)
if (light != 0):
print light
break
else:
i+=1
if (i == 10):
print light
break

Теперь я хочу запустить его в PHP на моем Raspberry Pi с

echo system("/var/www/light.py")

но ответ с сайта ничего не дает.
Я даю всем файлам разрешения с помощью chmod + x, но это ничего не изменило.
Если я наберу

python /var/www/light.py

в консоль это работает.

0

Решение

Проблема в том, что вы запускаете веб-сервер под каким-либо пользователем, который не имеет прав на использование smbus функции, которые вы используете.

Вы можете проверить это, запустив что-то вроде su www-data /usr/bin/python /var/www/light.py (хотя детали будут меняться в зависимости от ваших настроек, конечно). Если это не помогает, вы знаете, что это ваша проблема. (Кроме того, вы увидите трассировку, которая может быть полезна.)

Запуск веб-сервера от имени пользователя с наименьшим количеством привилегий — отличная идея, но запуск его с меньше привилегий, чем это возможно, очевидно, нет. 🙂

Большинство привилегий в системах * nix контролируются правами доступа к файлам пользователей / групп, поэтому ответ, вероятно, заключается в добавлении пользователя веб-сервера в группу, которой принадлежит smbus, Как и подразумевается в сообщении на форуме, которое вы нашли, PHP exec и python-smbus, эта группа обычно называется i2c, так что если ваш пользователь веб-сервера называется www-dataвы бы запустили:

sudo adduser www-data i2c

Как примечание, в будущем не игнорируйте возвращаемое значение от вызова другой программы. Если он возвращает 1 или что-либо, кроме 0, это означает, что программа завершилась неудачно, и поэтому вы не получаете никакого полезного вывода. (За пределами 0 или не 0 фактическое значение не стандартизировано, хотя 2 часто означает неверные аргументы.)


Между тем, у вас также есть вторая проблема.

Как документы для system объяснить, system не возвращает вывод выполненной команды.

Документы подразумевают, что вы хотите посмотреть на passthru, но это, вероятно, не то, что вы хотите. Как system, passthru выводит вывод на ваш стандартный вывод, а не возвращает его; единственное отличие состоит в том, что он сбрасывает его без фильтрации перевода строки.

Если вы хотите получить вывод, а затем повторить его, то, что вы, вероятно, хотите здесь exec, с output аргумент:

Если output аргумент присутствует, тогда указанный массив будет заполнен каждой строкой вывода команды.

2

Другие решения

Других решений пока нет …