我的Ruby CGI应用程序非常简单,我想调用Python脚本,例如youtube-upload
或%x{youtube-dl --help}
youtube-dl
为简单起见,我想只打印#!/usr/bin/ruby
require "cgi"
cgi=CGI.new(:accept_charset => "UTF-8")
url=cgi['url']
puts "Content-Type: text/plain; charset=\"UTF-8\""
puts "Access-Control-Allow-Origin: *"
puts
puts url
puts "-----------------------------------"
puts %x{youtube-dl --help 2>&1}
Python脚本的帮助页面。所以我的Ruby脚本也非常简单:
ytdl
然后我可以用http://example.com/cgi-bin/ytdl?url=a_youtube_url调用这个名为Traceback (most recent call last):
File "/usr/bin/youtube-dl", line 5, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python3.4/site-packages/pkg_resources/__init__.py", line 36, in <module>
import plistlib
File "/usr/lib/python3.4/plistlib.py", line 65, in <module>
from xml.parsers.expat import ParserCreate
File "/usr/lib/python3.4/xml/parsers/expat.py", line 4, in <module>
from pyexpat import *
ImportError: /usr/lib/python3.4/lib-dynload/pyexpat.cpython-34m.so: undefined symbol: XML_SetHashSalt
的CGI应用程序。不幸的是,我从Python解释器中得到的错误消息很多,无法导入某些包,尤其是站点包:
daemon
我想我会配置我的Apache 2 Web服务器为Python interpereter提供一些环境变量,在那里它可以找到包。不幸的是我没有使用Python的经验,直到现在我才学习Ruby。我的Apache服务器以用户daemon
运行CGI应用程序,当我以youtube-dl
身份登录时,我可以运行puts %x{env}
脚本而不会显示错误消息。
Apache为我的CGI应用程序提供了这些环境(使用UNIQUE_ID=VZN9RyX3N7MAAAs95zsAAAAI
RUBYOPT=rubygems
GEM_HOME=/home/XXXXXX/.gem/ruby/2.2.0
HTTP_USER_AGENT=Opera/9.80 (X11; Linux i686) Presto/2.12.388 Version/12.16
HTTP_HOST=xx.xxx.xx.xxx
HTTP_ACCEPT=text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.9
HTTP_ACCEPT_ENCODING=gzip, deflate
HTTP_CONNECTION=Keep-Alive
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/XXXXXX/.gem/ruby/2.2.0/bin:/home/XXXXXX/util
LD_LIBRARY_PATH=/opt/lampp/lib:/opt/lampp/lib
SERVER_SIGNATURE=
SERVER_SOFTWARE=Apache/2.4.9 (Unix) OpenSSL/1.0.1g PHP/5.5.11 mod_perl/2.0.8-dev Perl/v5.16.3
SERVER_NAME=xx.xxx.xx.xxx
SERVER_ADDR=xx.xxx.xx.xxx
SERVER_PORT=80
REMOTE_ADDR=xx.x.xxx.xxx
DOCUMENT_ROOT=/opt/lampp/htdocs
REQUEST_SCHEME=http
CONTEXT_PREFIX=/cgi-bin/
CONTEXT_DOCUMENT_ROOT=/opt/lampp/cgi-bin/
SERVER_ADMIN=you@example.com
SCRIPT_FILENAME=/opt/lampp/cgi-bin/ytdl
REMOTE_PORT=37798
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.1
REQUEST_METHOD=GET
QUERY_STRING=
REQUEST_URI=/cgi-bin/ytdl
SCRIPT_NAME=/cgi-bin/ytdl
打印):
ENV['PYTHONHOME']=value
同时我意识到当我设置环境变量时(在Apache配置httpd.conf中使用SetEnv指令,或者在我的Ruby脚本中使用Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'
)
将PYTHONHOME称为空字符串“”或“/ usr / lib”,错误消息消失,我得到另一个:
ENV['PYTHONHOME']="/usr/lib"
ENV['PYTHONPATH']="/usr/lib/python3.4"
当我设置:
File "/usr/bin/youtube-dl", line 5, in <module>
from pkg_resources import load_entry_point
ImportError: No module named 'pkg_resources'
我收到另一条错误消息:
HTML5 datalist
所以我的问题是,如何配置我的Apache 2网络服务器以使Python脚本运行并使其可以从其他应用程序调用?
答案 0 :(得分:1)
在子shell中运行应用程序时,您必须了解为该shell和应用程序设置的环境。 PATH和变量将不存在或非常有限,这可能会影响其查找库的能力。
编写一个小CGI,输出传递给脚本的Apache变量和环境,作为网页或日志或文件,并检查结果。
此外,权限和用户将是服务器设置的任何内容,通常非常有限。
另外,请认真考虑不使用CGI。而是使用更现代和灵活的东西。 Sinatra与Apache一起很好地使用像Passenger这样的东西将它们粘合在一起。 Sinatra使得Web服务变得非常简单,并且实际上运行良好,您通常可以在没有像Apache这样的重量级服务器的情况下工作,特别是在开发,测试和早期生产阶段。我有一个内部使用的API来处理许多关键的企业请求,它只是巡航。