在Apache2中执行Python脚本

12

我正在尝试使用Apache执行一个Python程序。然而,Apache只会提供该文件而不实际执行它。该文件的权限为r/w/x,位于/var/www目录下。我将在此之后发布httpd.conf和程序代码的内容。我还尝试将Python脚本作为.cgi文件运行,但也没有成功。同时,我已经将mod_pythonmod_wsgi模块加载到了Apache中。

Python示例:

#!/usr/bin/python

# enable debugging
import cgitb
cgitb.enable()

print "Content-Type: text/plain\r\n\r\n"
print

print "Hello World!"

httpd.conf:

AddHandler cgi-script .cgi .pl
AddHandler python-program .py

我知道httpd.conf文件很小,但是在我安装apache时,这个文件里什么都没有。我还要说明的是,这只是为了学习如何在apache中运行python的基础知识,不是为了生产使用。 感谢您的帮助!

编辑

我使用的操作系统是Ubuntu 10.04,apache版本为2。我有python版本为2.6,当调用#!/usr/bin/env python时会自动使用它。
我遇到了两个主要错误,第一个错误是即使文件和文件夹的权限为777,文件也无法被找到。来自日志的错误信息是

[Sun Feb 05 13:29:44 2012] [error] [client 192.168.1.3] File does not exist: /var/www/poit-0.1

这个错误是针对一个我没有编写的不同的Python脚本。奇怪的是,当从浏览器窗口访问文件夹时,该文件出现在索引中。然而,当我导航到该文件时,我会遇到上述错误。

我遇到的另一个错误是头部过早结束。错误如下:

[Sun Feb 05 12:10:19 2012] [error] (8)Exec format error: exec of '/var/www/pyth.py' failed
[Sun Feb 05 12:10:19 2012] [error] [client 192.168.1.3] Premature end of script headers: pyth.py

从技术上讲,CGI脚本并不是在httpd中运行的... - Ignacio Vazquez-Abrams
我知道它们不会在实际文件中运行,因为这是一个配置文件... - tpar44
不,它们不在同一个进程中运行;CGI程序作为独立的进程运行。 - Ignacio Vazquez-Abrams
6个回答

20

httpd.conf的第一行:AddHandler cgi-script .cgi .pl并不相关,因为您正在测试Python脚本而不是Perl脚本。您应该在Python脚本的位置中定义这些指令,并告诉Apache它应该在那个位置执行CGI脚本:Options +ExecCGI。以下代码段可以作为开始:

<Directory /path/to/sample.py />
  Options +ExecCGI
  AddHandler cgi-script .py
</Directory>

附加说明 1:

根据我的最后一条评论,请尝试这个脚本。它应该会输出关于cgi环境的信息。

#!/usr/bin/python
import cgi
cgi.test()

附加说明2:

我使用了上述配置,使您的脚本正常运行。问题在于该脚本是使用Python2编写的,而Apache调用执行脚本的默认解释器是Python3(至少在我的情况下是这样,您的情况也很可能如此)。

以下是Hello World脚本的Python3版本:

#!/usr/bin/env python

# enable debugging
import cgitb
cgitb.enable()

print("Content-Type: text/plain;charset=utf-8")
print()

print("Hello World!")

附录 3:

对于第一个错误,请确保您尝试部署的任何目录和文件的权限和所有权已正确设置。并尝试将这些指令添加到 httpd.conf 中:

Order allow,deny
Allow from all

这将为您得到以下结果:

<Directory /path/to/sample.py />
  Options +ExecCGI
  AddHandler cgi-script .py
  Order allow,deny
  Allow from all
</Directory>

第二个错误,除非我漏掉了什么,否则看起来像是Apache正在调用Python 3解释器来执行您的脚本。为了排除这种可能性,您可以尝试以下操作:

ls -al /usr/bin/python*

这将列出您的系统上可用的 Python 解释器。如果您有多个解释器,您将得到类似于此输出:

/usr/bin/python -> python3*
/usr/bin/python2.6*  
/usr/bin/python3*  

如果不是这样,输出将会是这个:

/usr/bin/python -> python2.6*
/usr/bin/python2.6*  
为了确保您没有遇到这个问题,请尝试使用此修改后的示例脚本:
#!/usr/bin/python2.6

# enable debugging
import cgitb
cgitb.enable()

print "Content-Type: text/plain\r\n\r\n"
print

print "Hello World!"
你会注意到我明确提到了apache应该调用的解释器版本,这很丑陋。但为了测试,你可以这样做。当然,你应该将#!/usr/bin/python2.6映射到你服务器上的任何二进制文件,并确保不要混合使用Python 3兼容代码和Python 2解释器,反之亦然。

是的,我知道第一行与问题无关,而且我应该将其映射到特定目录,但是我现在的主要目标是让它正常工作。你提出的建议没有起作用。这可能与脚本本身有关,因为日志中还有一个错误,即标题过早结束。 - tpar44
顺便提一下,您不应同时启用mod_python和mod_wsgi,它们是不兼容的。而且它们每个都需要不同的部署配置。而您现在尝试做的,也就是将python webapp作为cgi脚本部署,两者都不需要。因此,您可以禁用它们以减少误导性干扰的风险。 - b2Wc0EKKOvLPn
所以Apache不允许我运行第二个脚本,我不确定为什么,因为我完全按照你说的做了。第三个脚本也无法运行,但是当我用./从命令行运行它时,我会在第一个打印语句之前得到“附近意外标记`print'”的错误。如果我通过调用"python"来运行它,那么它就可以正常工作。我认为这里有一些问题与shebang有关,但我不确定它可能是什么。 - tpar44
请查看我的第三个补充说明。 - b2Wc0EKKOvLPn
1
先生,您救了我的一天。我认为“Order”和“Allow all”部分拯救了我。谢谢您,祝您每天都过得愉快。 - user3290525
显示剩余2条评论

3

关于“执行格式”错误的回复。

我之前也遇到过这个问题,收到了相同(晦涩)的错误信息。

我在我的Windows机器上使用Notepad ++开发Python(3)脚本以通过CGI使用,并将它们上传到Linux服务器。

经过长时间的挣扎,我发现此问题与行结尾有关,您需要将Windows行结尾(\r\n)转换为UNIX行结尾(\n)

在Notepad ++(6.1.5)中,您可以通过转到编辑菜单并选择EOL转换选项,然后保存文件来实现此目的。


3
只是一个部分回答,但希望能对一些在谷歌上搜索这个问题的可怜人有所帮助。 - nibbler
作为替代方案,您可以在大多数Linux系统上使用dos2unix工具。该命令行实用程序会扫描指定的文件并转换所有行结尾(以及可能的其他一些内容,但行结尾很重要)。 - nibbler

1

**适用于 Apache2 版本 2.4

sudo apt-get install python
sudo apt-get install apache2

编辑文件 /etc/apache2/conf-enabled/serve-cgi-bin.conf

====注释掉旧部分,添加以下代码:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AddHandler cgi-script .py
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>

=========================================

编辑文件/etc/apache2/apache2.conf ***在下面添加代码:

<Directory "/var/www/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>

<Directory "/var/www/cgi-bin">
Options All
</Directory>

<Directory /usr/local/apache2/cgi-bin>
Require all granted
</Directory>

注意!
use for apache2.4 
  file python keep in directory: /var/www/cgi-bin/
  You can test :go to http://localhost/cgi-bin/<namefile>.py

referrence https://www.linux.com/blog/configuring-apache2-run-python-scripts


0
在我的情况下,这是一个微不足道的问题。我必须添加这行代码:
#!/usr/bin/python3

我想在每个要运行的.py文件顶部添加代码。然后,一切开始正常工作。

0

我有同样的症状,我的配置看起来与上面的答案相比还不错。

我发现我的新安装没有配置加载mod_cgi.so

加载所需的模块看起来有点像这样。如果重新启动服务器会出现文件未找到的错误,请找出文件在哪里并相应地调整路径。

LoadModule cgi_module modules/mod_cgi.so


-5

我假设你正在使用火狐浏览器。我在网上的某个地方读到,这可能与安装在计算机上的火狐插件有关。

我也遇到了这个错误,我使用的是火狐20。切换到Opera后,我没有再遇到任何错误,Python脚本似乎也能正常执行。

编辑:实际上,我忽略了一个eval()方法调用,它将"("和")"添加到脚本结果中,导致我的失败。一旦我删除了它们,它就对我起作用了。

我注意到你没有发布JavaScript、HTML或者其他你用来调用脚本的内容。 也许你可以为我们发布一下?我从一个博客网站直接复制/粘贴了一个示例,而没有看我复制了什么。那是我的错误。


1
如果Apache正在提供服务器端脚本,则这不是客户端问题。客户端不应该直接访问它们。 - tom
我已经有一段时间没有发布这个答案了。在我的问题中,我正在从客户端调用服务器端方法,这需要客户端知道方法名称的知识。这不是我设计的项目。在这种情况下,它部分是客户端问题。(我正在处理的是一个Web应用程序,而不是网站) Opera在Web标准方面最为兼容,因此安装Opera可以帮助调试问题,特别是基于浏览器的问题。 - NuclearPeon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接