Apache CGI 程序中设置 LD_LIBRARY_PATH 为什么没有用呢?

Web、Mail、Ftp、DNS、Proxy、VPN、Samba、LDAP 等基础网络服务
回复
头像
nicegiving
帖子: 125
注册时间: 2008-07-03 19:25

Apache CGI 程序中设置 LD_LIBRARY_PATH 为什么没有用呢?

#1

帖子 nicegiving » 2010-09-01 14:19

大家好,这个问题我找了好久都没有解决,现在在这里提出来,希望大家给点帮助, 提前谢过!

事情是这样的,我需要在cgi程序里面调用一个shell的命令,这个shell命令的执行依赖于一个外部的库,我是手动安装的这个库,然后为这个库设置了 LD_LIBRARY_PATH 环境变量,现在是shell里面,这个命令的执行没有任何问题,但是在apache服务器里面使用cgi程序调用执行,就出现了奇怪的错误,见下面的详细问题描述。

详细问题描述:
[0]操作系统: ubuntu desktop edition 9.04
apache 版本: apache2
CGI 程序编写语言: python 2.6.5
外部程序库: BALL 1.2 (生物化学算法库)

[1]如何设置 LD_LIBRARY_PATH 环境变量
大家可能知道,在ubuntu 8.10 以上的版本中, LD_LIBRARY_PATH 环境变量被取消了,传统的设置方法没有用,我是通过下面的方法来设置的:

代码: 全选

zzm@zzm-desktop:~$ echo STARTUP=\"/usr/bin/env LD_LIBRARY_PATH=\${LD_LIBRARY_PATH} \${STARTUP}\" | sudo tee /etc/X11/Xsession.d/90preserve_ld_library_path
zzm@zzm-desktop:~$ sudo reboot
具体是参考来这个页面里面的讨论: https://bugs.launchpad.net/ubuntu/+bug/366728

[2]apache配置

代码: 全选

zzm@zzm-desktop:/etc/apache2$ more httpd.conf
DirectoryIndex index.html index.html.var index.htm
AddType text/html .htm .html .py
AddHandler cgi-script .cgi .py

zzm@zzm-desktop:/etc/apache2$ more sites-available/default
<VirtualHost *:80>
	ServerAdmin [email protected]
	SetEnv LD_LIBRARY_PATH /home/zzm/ProgramFiles/BALL/BALL-1.2/lib/Linux-i386-g++_4.1.3
	DocumentRoot /var/www
	<Directory />
		Options FollowSymLinks
		AllowOverride None
	</Directory>
	<Directory /var/www/>
		Options Indexes FollowSymLinks MultiViews ExecCGI
		AllowOverride None
		Order allow,deny
		allow from all
		AddHandler mod_python .py
		PythonHandler mod_python.publisher
		PythonDebug on
	</Directory>

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

	ErrorLog /var/log/apache2/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog /var/log/apache2/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>
[3]CGI 脚本

代码: 全选

#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi
import cgitb
import os,sys,re

cgitb.enable()
server_line = 'Content-type: text/html\n'

def main():
    print server_line
    cmd = '/home/zzm/ProgramFiles/BALL/BALL-1.2/lcs/lcs -i 1dwd.pdb'
    aa = os.popen(cmd).read()
    print aa
    
if __name__ == '__main__':
    main()
我试验了在此脚本中显示的重新设置环境变量,还是没有任何作用,设置语句如下:

代码: 全选

<... 略 ...>
cgitb.enable()
server_line = 'Content-type: text/html\n'

# 显示设置环境变量
os.environ['LD_LIBRARY_PATH'] = '/home/zzm/ProgramFiles/BALL/BALL-1.2/lib/Linux-i386-g++_4.1.3:/usr/local/lib'

def main():
<... 略 ...>
[4]输出结果
1. shell中执行此命令的结果

代码: 全选

zzm@zzm-desktop:/var/www/cgi-bin$ /home/zzm/ProgramFiles/BALL/BALL-1.2/lcs/lcs -i 1dwd.pdb 
Grid space: 1
Number of pockets: 3
Density: 0.5
SSS threshold: 6
Grid  Size: (62 46 54)
Grid origin: (-31 -23 -27)
Mass center: (41.5615 20.6018 19.6968)
Number of grid points: 154008
Number of redundant pockets 364
Done!
Total used time: 0.860006 seconds
2. apache中执行此cgi程序的运行结果

代码: 全选

Grid space: 1 Number of pockets: 3 Density: 0.5 SSS threshold: 6 
从上面的结果可以看出, 在apache中执行此cgi程序,环境变量似乎传递过去了,有了几行输出,但是程序到此似乎就停止了,后面的输出没有了,很是奇怪!

3. shell中执行此cgi程序的运行结果

代码: 全选

zzm@zzm-desktop:/var/www/cgi-bin$ python test.cgi
Content-type: text/html

Grid space: 1
Number of pockets: 3
Density: 0.5
SSS threshold: 6
Grid  Size: (62 46 54)
Grid origin: (-31 -23 -27)
Mass center: (41.5615 20.6018 19.6968)
Number of grid points: 154008
Number of redundant pockets 364
Done!
Total used time: 1.03 seconds
4. 没有配置好 LD_LIBRARY_PATH 环境变量的程序运行结果:

代码: 全选

zzm@zzm-desktop:~$ lcs -i 1dwd.pdb 
lcs: error while loading shared libraries: libBALL.so: cannot open shared object file: No such file or directory
[5]apache 错误日志

代码: 全选

[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] , referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] ---------------------------------------------------, referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] , referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] FATAL: uncaught exception!, referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] , referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] ---------------------------------------------------, referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] , referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] ---------------------------------------------------, referer: http://localhost/test.html
[Wed Sep 01 14:12:57 2010] [error] [client 127.0.0.1] , referer: http://localhost/test.html
错误日志显示, 上面的程序执行一半就停止了是遇到了“uncaught exception”,但是为什么会这样呢,是由于环境变量没有设置好,还是别的问题,另外,有没有办法可以将这个异常的详细信息打印出来看看呢?

以上就是所有的错误信息,我是在sites-available/default中使用 SetEnv 来配置的shell环境变量,似乎传递过去了,但是如同上面提到的那样,程序执行一半就停止了,这是为什么呢?

另外,我试验了在 httpd.conf 和 default 文件里面分别都配置了 SetEnv 和 PassEnv, 如下:

代码: 全选

zzm@zzm-desktop:/etc/apache2$ more httpd.conf
DirectoryIndex index.html index.html.var index.htm
AddType text/html .htm .html .py
AddHandler cgi-script .cgi .py

SetEnv LD_LIBRARY_PATH /home/zzm/ProgramFiles/BALL/BALL-1.2/lib/Linux-i386-g++_4.1.3
PassEnv LD_LIBRARY_PATH  

zzm@zzm-desktop:/etc/apache2/sites-available$ more default
<VirtualHost *:80>
	ServerAdmin [email protected]

	SetEnv LD_LIBRARY_PATH /home/zzm/ProgramFiles/BALL/BALL-1.2/lib/Linux-i386-g++_4.1.3
	PassEnv LD_LIBRARY_PATH
<... 以下省略 ...>
结果还是和上面一样,出了同样的问题!而且在这样的配置之后,apache2 重新启动的时候也报错了(PassEnv variable LD_LIBRARY_PATH was undefined), 详细启动信息如下:

代码: 全选

$ sudo /etc/init.d/apache2 restart
 * Restarting web server apache2
[Wed Sep 01 14:41:15 2010] [warn] PassEnv variable LD_LIBRARY_PATH was undefined
[Wed Sep 01 14:41:15 2010] [warn] PassEnv variable LD_LIBRARY_PATH was undefined
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
 ... waiting [Wed Sep 01 14:41:16 2010] [warn] PassEnv variable LD_LIBRARY_PATH was undefined
[Wed Sep 01 14:41:16 2010] [warn] PassEnv variable LD_LIBRARY_PATH was undefined
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName  [ OK ]
那位高手可以帮帮我啊, 万分感谢!
头像
nicegiving
帖子: 125
注册时间: 2008-07-03 19:25

Re: Apache CGI 程序中设置 LD_LIBRARY_PATH 为什么没有用呢?

#2

帖子 nicegiving » 2010-09-02 13:53

自问:
在[4].2 中 apache中执行此cgi程序的运行结果来看,环境变量的设置是没有问题的,确实已经传递给CGI程序了,但是为什么会执行一半就停止了呢? 原因可能出现在你在CGI里面调用的那个程序上面,在shell里面可以正常执行,那就说明程序本身没有问题,问题就在于CGI程序执行的时候没有shell中的环境变量,你传递了一个,不错,但是是不是还需要其他的呢?

自答:
查察之下发现真实这样,被调用的程序还需要一个环境变量,由于此环境变量没有传递,导致程序执行失败,因此只输出了部分的执行内容!

----
好了,现在问题解决! 谢谢各位!
回复