我正在尝试在 Apache2 中启用 mod-nss 模块。因此,在完成必要的操作后,我尝试验证模块是否确实已加载。
询问 apachectl
# apachectl -M | grep nss
nss_module (shared)
询问守护进程本身:
/usr/sbin/httpd-prefork -M | grep nss
-> No output
所以,我得到两个不同的输出:
- apachectl 声称 mod_nss 模块已加载。
- httpd 声称 mod_nss 模块未加载。
之后,我决定列出这两个模块(而不是仅 grep 查找特定模块),对输出进行排序,然后比较它们。
# diff -Nur httpd_sorted_modules apachectl_sorted_modules
--- httpd_sorted_modules 2016-09-01 13:59:16.297139860 +0200
+++ apachectl_sorted_modules 2016-09-01 13:59:26.680985223 +0200
@@ -15,11 +15,15 @@
expires_module (shared)
http_module (static)
include_module (shared)
+ info_module (shared)
log_config_module (shared)
mime_module (shared)
mpm_prefork_module (static)
negotiation_module (shared)
+ nss_module (shared)
+ php5_module (shared)
reqtimeout_module (shared)
+ rewrite_module (shared)
setenvif_module (shared)
so_module (static)
socache_shmcb_module (shared)
正如您所看到的,与 httpd 相比,apachectl 显示了 4 个额外的模块。为什么会发生这种情况?我应该信任哪一个?
我试图看看它们之间有什么区别,但我失败了。以下是我的一些发现:
apachectl 似乎是一个独立的二进制文件
# ls -l `which apachectl`
-rwxr-xr-x 1 root root 3548 Aug 23 13:11 /usr/sbin/apachectl
来自 apache pkg:
# rpm -qf `which apachectl`
apache2-2.4.16-12.1.x86_64
这实际上是用来减轻对 httpd 的控制。显然,与 SystemD 或 SySVinit 一起使用是有区别的。以下是来自 man apachectl 页面的引用:
当以直通模式运行时,apachectl 可以获取 httpd 二进制文件可用的所有参数。
apachectl [ httpd-argument ]
当在 SysV init 模式下运行时,apachectl 接受简单的单字命令,定义如下。
apachectl command
因此,如果我请求 -h 帮助选项:
# apachectl -h
Usage: /usr/sbin/httpd-prefork [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
-D name : define a name for use in <IfDefine name> directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed vhost settings
-t -D DUMP_RUN_CFG : show parsed run settings
-S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t : run syntax check for config files
-T : start without DocumentRoot(s) check
-X : debug mode (only one worker, do not detach)
所以看起来它正在使用/usr/sbin/httpd-prefork
或者至少是它所说的。
但让我们尝试看看“httpd”在后台使用什么:
# which httpd
/usr/sbin/httpd
这似乎是一个符号链接:
# ls -l `which httpd`
lrwxrwxrwx 1 root root 23 Aug 25 13:28 /usr/sbin/httpd -> /usr/sbin/httpd-prefork
所以它使用的/usr/sbin/httpd-prefork
是与 apachectl 似乎使用的相同的。例如,如果我请求 -h 帮助,我会得到:
# /usr/sbin/httpd-prefork -h
Usage: /usr/sbin/httpd-prefork [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
-D name : define a name for use in <IfDefine name> directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed vhost settings
-t -D DUMP_RUN_CFG : show parsed run settings
-S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t : run syntax check for config files
-T : start without DocumentRoot(s) check
-X : debug mode (only one worker, do not detach)
这与我得到的相同apachectl -h
。
然而,这个来自另一个包:
# rpm -qf /usr/sbin/httpd-prefork
apache2-prefork-2.4.16-12.1.x86_64
除此之外,我想不出当我查询加载的模块时得到不同输出的原因:/
对于那些想知道的人,我使用 OpenSUSE Leap 42.1 作为我的 Linux 发行版,并使用 Prefork MPM 运行 Apache。
答案1
鉴于您的清单:
# ls -l `which apachectl`
-rwxr-xr-x 1 root root 3548 Aug 23 13:11 /usr/sbin/apachectl
你的二进制文件不太可能apachectl
是一个“独立的二进制文件”(它太小了:一个合理的二进制文件会大10-20倍)。其实就是一个shell脚本。当你执行
apachectl -M
shell 脚本首先从其配置文件中获取附加参数,并-M
在执行 httpd 二进制文件时将这些参数放在 之前。
为了讨论的目的,我将参考Apache 的 git 镜像,以及模板脚本apachectl.in
。当然,不同版本的 Apache 有所不同,但不同版本的共同点apachectl
是脚本会检查配置设置,其中可能包括服务器模块的位置。在模板的当前版本中,它位于注释下方
# pick up any necessary environment variables
如果不设置这些变量就直接运行httpd-prefork
,将无法正常运行。这解释了为什么它报告模块未加载。如果您没有grep
输出,您可能会得到一份信息更丰富的报告,例如,可能根本没有列表。