【问题标题】:microcrontroller output to python cgi scriptmicrocrontroller 输出到 python cgi 脚本
【发布时间】:2009-08-18 03:22:26
【问题描述】:

我买了这个温度传感器记录器套件:http://quozl.netrek.org/ts/。它与提供的 C 代码配合得很好,我喜欢使用 python,因为它很简单,所以我用 python 编写了一个脚本来显示微控制器的输出。我只有一个连接到套件的温度传感器。我希望将温度显示在网页上,但似乎无法弄清楚,我很确定这与具有 \r\n DOS EOL 字符和 linux web 的微型计算机的输出有关服务器没有正确解释它。我的书说“根据您使用的 Web 服务器,您可能需要进行配置更改以了解如何提供 CGI 文件。”我正在使用 debian 和 apache2,基本的 cgi 脚本工作正常。

这是我仅将传感器显示到控制台的代码(这很好用):

import serial

ser = serial.Serial('/dev/ttyS0', 2400)

while 1:
   result = ser.readline()
   if result:
      print result

这是我的 test.cgi 脚本,它可以工作:

#!/usr/bin/python
print "Content-type: text/html\n"
print "<title>CGI Text</title>\n"
print "<h1>cgi works!</h1>"

这是我开始显示 temp 的 cgi 脚本(不起作用 - 500 内部服务器错误):

#!/usr/bin/python
import sys, serial

sys.stderr = sys.stdout

ser = serial.Serial('/dev/ttyS0', 2400)

print "Content-type: text/html\n"

print """
<title>Real Time Temperature</title>

   <h1>Real Time Temperature:</h1>
"""

#result = ser.readline()
#if result:
print ser.readline()

如果我在控制台中运行 python rtt.cgi,它会输出正确的 html 和温度,我知道这不是实时的,并且每次用户想要查看温度时都必须重新加载页面,但是这些东西将来会出现。从我的 apache2 错误日志中它说: 来自脚本的格式错误的标头。错误头=文件“/usr/lib/cgi-bin/rtt.c:rtt.cgi

【问题讨论】:

  • is "#!/usr/bin/pythonimport sys, serial" 是复制到 SO 时的拼写错误,还是在您的文件中?
  • 当你在命令行运行 rtt.cgi 时,'print ser.readline()' 的输出是什么样的?
  • Neil:这是一个错字 ryan_s:当我从命令行运行 rtt.cgi 时,它会输出带有温度的 html,就像我希望它显示在网页上一样。它实际上读取串行端口并获取数据并将其打印在 html 中应该进入的位置。

标签: python serial-port cgi


【解决方案1】:

我猜你的 CGI 运行的执行上下文无法从串口完成read()

顺便说一句,Python 标准库在编写 CGI 脚本方面比您在此处所做的要好得多;甚至基本的字符串处理也提供了一种更好的方法来将结果(假设您的代码具有read() 他们的必要权限)插入到 HTML 中。

至少我会推荐类似的东西:

#!/usr/bin/python
import sys, serial

sys.stderr = sys.stdout
ser = serial.Serial('/dev/ttyS0', 2400)

html = """Content-type: text/html

<html><head><title>Real Time Temperature</title></head><body>
<h1>Real Time Temperature:</h1>
<p>%s</p>
</body></html>
"""  % ser.readline()   # should be cgi.escape(ser.readline())!
ser.close()
sys.exit(0)

请注意,我们只是将 ser.readline() 的结果插入到我们的字符串中,使用 % 字符串运算符。 (顺便说一句,您的 HTML 缺少 &lt;html&gt;, &lt;head&gt;&lt;body&gt;&lt;p&gt;(段落)标签)。

这仍然存在问题。例如,我们真的应该至少 import cgi 将外部数据包装在其中,以确保 HTML 实体正确替换任何保留字符等)。

我建议进一步阅读:[Python 文档]:http://docs.python.org/library/cgi.html

【讨论】:

  • 我仍然收到 500 内部服务器错误,上面的代码。我还像在 cmets 中一样导入了 cgi 并做了 cgi.escape。我应该将 cgi.escape 添加到 ser.close() 吗?
  • 您是否确认 ser.readline() 在您的 Web 服务器执行时具有足够的权限来操作?这是我建议的第一部分,也是唯一与您的 500 错误真正相关的部分。其余的只是关于更好的 CGI 脚本的建议。请记住,您的 Web 服务器可能以某种“无人”的身份运行 CGI 脚本(除非您使用某种 suExec 功能)并且它可能正在使用 chroot 系统调用...这将阻止访问 /dev/ ttyS* 等)。我认为这些是您问题的根源。
  • 我正在使用 debian 安装,并使用 apt 安装 apache2。我没有使用我知道的 mod suExec,但 mods_enabled 文件夹中有一个 suexec.load。我认为 apache 用户是 www-data(它的默认值)。我尝试了 chmod o+rwx /dev/ttyS0 和它的地狱 chmod g+rwx /dev/ttyS0 ,我仍然得到 500 错误。这是我对 apache2.conf 文件的添加以允许执行 cgi 脚本: # 添加以允许执行 cgi ScriptAlias /cgi-bin/ /var/www/cgi-bin/ AddHandler cgi-script .cgi .py .pl 选项 +Execcgi AddHandler cgi-script .cgi .py .pl
  • whoops.. # 添加以允许执行 cgi ScriptAlias /cgi-bin/ /var/www/cgi-bin/ AddHandler cgi-script .cgi .py .pl <directory> 选项 +Execcgi AddHandler cgi-script .cgi .py .pl </directory>
  • 我想我很困惑如何确定 ser.readline() 在被 web 服务器执行时是否具有足够的权限。
【解决方案2】:

再来一次:

# Added to allow cgi-bin to execute cgi, python and perl scripts
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
AddHandler cgi-script .cgi .py .pl
<Directory /var/www>
Options +Execcgi
AddHandler cgi-script .cgi .py .pl
</Directory>

【讨论】:

    【解决方案3】:

    迈克尔,

    看起来问题肯定是权限,但是,您不应该尝试使您的脚本具有 /dev/ttyS0 的权限。您可能需要做的是生成另一个进程,其中您要做的第一件事是将您的组更改为 /dev/ttyS0 设备的组。在我的“拨出”框中,您可能会有所不同。

    您需要导入 os 包,查看文档中的流程参数,在该页面上您会找到一些允许您更改所有权的功能。您还需要使用 os 包中的 Process Management 中的功能之一,这些功能会产生进程,但您需要选择一个从产生的进程返回数据的功能。 subprocess 包可能会更好。

    你需要spawn另一个进程的原因是CGI脚本需要在Apache进程下运行并且spawn进程需要访问串口。

    如果我在接下来的几天里有机会,我会尝试为你准备一些东西,但试试看,不要等我。

    另外一件事,所有 HTTP 标头都需要以两个 CRLF 序列结尾。所以你的标题需要是:

    打印“内容类型:文本/html\r\n\r\n”

    如果您不这样做,您的浏览器可能不知道标头何时结束以及实体数据何时开始。阅读 RFC-2616

    ~卡尔

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2017-12-09
      • 2013-03-21
      • 2017-03-12
      • 2018-05-30
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 2011-10-24
      相关资源
      最近更新 更多