我有这个/etc/profile.d/myfile.sh
:
export MYVAR=myval
我也有PassEnv MYVAR
<virtualhost>
apache conf 目录的一部分中的行。
这让我可以做如下事情:
$ echo $MYVAR
myval
$ python
>>> import os; os.getenv('MYVAR')
'myval'
$ sudo echo $MYVAR
myval
$ sudo -i
root# echo $MYVAR
myval
但是,尽管如此,我还是得到了:
root# /sbin/service httpd restart
/sbin/service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [Mon Oct 22 14:44:02 2012] [warn] PassEnv variable MYVAR was undefined
[ OK ]
我所有尝试从我的 wsgi 脚本中访问 MYVAR 的尝试都失败了。
有什么想法吗?我是不是做了一些明显错误的事情?
编辑更多细节
我有一大群计算机/虚拟机和一大群开发人员在从事一大群项目。我需要一个简单的保存环境信息的中心位置,最常见的是“环境”(dev/stage/prod)。我们得到的方案(通过*.wsgi
编程进行修改)比我们想象的更脆弱。
我看到的主要选项是:
- 将内容放入 shell 环境中
- 把内容放到其他配置文件中
将事物放入 shell 环境是最好的,因为我们不需要编写更多重复的“我的环境是什么”代码。
答案1
Apache 不会读取全局用户配置文件。
最大的问题是你到底想为什么这么做?
您所做的通常是使用 Apache 的错误方式,但是因为不知道您要解决的实际问题,所以无法说出您应该做什么。
修改您的问题并说明您尝试设置哪些环境变量以及原因。
更新 1
不是具体你在做什么,但是 mod_wsgi 中的 SetEnv 不会设置进程范围的环境变量。它在 WSGI 环境字典中设置每个请求的变量。
PassEnv 与 SetEnv 相关,它会执行相同的操作,但它不是在 Apache 配置文件中定义的键/值,而是来自 Apache 继承的现有进程环境变量。
因此,这两个指令实际上都没有为在 mod_wsgi 下运行的 WSGI 应用程序设置进程范围的环境变量的效果。换句话说,它们无法像您希望的那样通过 os.environ 访问。
现在,具体到 PassEnv,如果您想要的是让 Apache 进程环境变量也可用于 mod_wsgi 下的 WSGI 应用程序,那么 PassEnv 实际上是多余的,因为 Apache 进程环境变量已经可用。
这是因为在嵌入模式下,WSGI 应用程序在 Apache 子工作进程内运行。即使在守护进程模式下,守护进程也是 Apache 父进程的直接分支(不执行任何单独的应用程序),因此实际上也在 Apache 内部运行。
因此,PassEnv 不是必需的,因为它们已经被设置了。
要按您想要的方式执行此操作,您只是在错误的地方执行此操作,因为 Apache init.d 启动脚本不会获取全局用户登录配置文件。
如果您使用的是 Apache Software Foundation 的 Apache 发行版,或者没有偏离太远的发行版,则设置 Apache 环境变量的正确位置是在与 Apache 可执行文件位于同一目录中的“envvars”文件中。在各种 Linux 发行版中,Apache 设置完全忽略该文件,而是需要将它们与系统特定的 Apache init.d 文件一起设置在某些特殊文件中。您在那里要做什么取决于 Linux 发行版。
正如我所说,Apache 不会读取该全局配置文件。
在正确的位置执行此操作,从技术上讲它可以工作,但依靠设置影响整个 Apache 的环境变量并不是我推荐的。
最好让 WSGI 脚本读取单独的配置文件,该文件设置系统状态,然后以此为基础。专门为此目的使用配置文件并不像依赖来自文件(不是项目的特定部分,而是 Apache init 脚本)的环境变量设置那样神奇。