以非超级用户身份安装 mod_perl

以非超级用户身份安装 mod_perl

译者/作者:cactus
出处:中国Perl协会 FPC(Foundation of Perlchina)
作者:Stas Bekman

原名:Installing mod_perl without superuser privileges

原文:http://www.perl.com/pub/a/2002/04/10/mod_perl.html

发表:April 10, 2002
请保护作者的著作权,维护作者劳动的结晶。

得分:19分 [查看文评]


就像大家从以前的文章里看到的,mod_perl 使Apache由两个组件组成: Perl 模块和 Apache 本身。虽然以非超级用户
权限安装Apache很简单,但是应该知道如何安装在非系统位置的Perl模块。本文我将论证几种方法来实现这个任务。

在这些例子里,我将用stas作为用户名,/home/stas作为该用户的私人目录。

安装Perl模块到选择的目录

既然不用超级用户权限,那么你就不允许安装到系统目录,象/usr/lib/perl5。你需要找到如何在你的私人目录安装这些
模块的方法。这很容易。

首先,你需要决定安装这些模块到什么地方。最简单的途径就是在你的私人目录下模仿与Perl有关的根目录文件系统的移植。
实际上,我们只需要两个目录:

/home/stas/bin
/home/stas/lib

既然他们会在第一个模块被安装时自动创建,那么我们就不必创建它们。99%的文件将被拷贝到lib目录下。有时候,当一些
模块随着Perl脚本发布的时候会被拷贝到bin目录。如果目录不存在会被创建。

让我们安装CGI.pm包,该包包含了一些其它CGI::*模块。通常,从CPAN库下载该包,解开该包并进入新建的目录里。

现在做一个标准的perl文件Makefile.PL去准备Makefile.但是这个时候让 MakeMaker 用你的Perl安装目录,而不是缺省的。

% perl Makefile.PL PREFIX=/home/stas

PREFIX=/home/stas 只是安装过程不同于通常的一部分。 注意如果你不在意MakeMaker如何选择剩下的目录,或者如果你正在
用一个需要显式指明所有目的目录的老版本,那么这样做:

% perl Makefile.PL PREFIX=/home/stas \
INSTALLPRIVLIB=/home/stas/lib/perl5 \
INSTALLSCRIPT=/home/stas/bin \
INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
INSTALLBIN=/home/stas/bin \
INSTALLMAN1DIR=/home/stas/lib/perl5/man \
INSTALLMAN3DIR=/home/stas/lib/perl5/man3

剩下的跟通常一样:

% make
% make test
% make install

make install 安装所有的文件到私人目录。注意所有丢失的目录会被自动创建,因此没有必要创建它们。

以下就是这么做的(稍微改动过):

正在安装 /home/stas/lib/perl5/CGI/Cookie.pm
正在安装 /home/stas/lib/perl5/CGI.pm
正在安装 /home/stas/lib/perl5/man3/CGI.3
正在安装 /home/stas/lib/perl5/man3/CGI::Cookie.3
正在写入 /home/stas/lib/perl5/auto/CGI/.packlist
正在追加安装信息到 /home/stas/lib/perl5/perllocal.pod

如果你不得不用显式目的参数,那么不用单个PREFIX参数,你会发现建立一个被调用的文件很有用。

例如, /.perl_dirs (这里 在我们的例子中是 /home/stas) 的内容包含:

PREFIX=/home/stas \
INSTALLPRIVLIB=/home/stas/lib/perl5 \
INSTALLSCRIPT=/home/stas/bin \
INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
INSTALLBIN=/home/stas/bin \
INSTALLMAN1DIR=/home/stas/lib/perl5/man \
INSTALLMAN3DIR=/home/stas/lib/perl5/man3

从现在起,任何时候你想本地化安装Perl模块就可以这样执行:

% perl Makefile.PL `cat /.perl_dirs`
% make
% make test
% make install

用这个方法,你可以很容易地保持不同Perl模块的存储。例如,你可以一个用作production Perl,另一个用作开发。

% perl Makefile.PL `cat /.perl_dirs.production`

或者

% perl Makefile.PL `cat ~/.perl_dirs.develop`

编写你自己的脚本找到本地已安装模块

这些Perl模块通常都放在四个主要目录。为了找到这些目录,执行:

% perl -V

输出包含重要的perl安装信息。最后你将看到:

Characteristics of this binary (from libperl):
Built under linux
Compiled at Apr 6 1999 23:34:07
@INC:
/usr/lib/perl5/5.00503/i386-linux
/usr/lib/perl5/5.00503
/usr/lib/perl5/site_perl/5.005/i386-linux
/usr/lib/perl5/site_perl/5.005
.

这向我们表明Perl特殊变量@INC的内容,这个特殊变量通常被Perl用来查找模块的。它等价于Unix shells里的PATH环境变量,
是用来查找可执行程序的。

注意Perl也在.目录(代表当前目录)查找模块,这是在以上输出目录里的最后的入口路径。
当然,这个例子来自5.00503版本的perl, 它安装在我的x86结构PC的Linux中。这就是为什么你看到了i386-linux和5.00503.
如果你的系统运行着不同版本的perl、操作系统、处理器或者芯片结构,那么一些目录会有不同的名字。

我也安装了perl 5.6.1版本到 /usr/local/lib/ ,所以当我这么做:

% /usr/local/bin/perl5.6.1 -V

你会看到:

@INC:
/usr/local/lib/perl5/5.6.1/i586-linux
/usr/local/lib/perl5/5.6.1
/usr/local/lib/site_perl/5.6.1/i586-linux
/usr/local/lib/site_perl

注意这还是Linux, 但是较新的perl版本用了奔腾的处理器(所以是i586而不是i386)。这对奔腾处理器的编译优化有用,
当二进制Perl扩展被创建时。

所有平台指定的文件,象已编译的C文件用XS或者SWIG去粘合Perl,应该进入类似i386-linux目录。

重点:当我们已经安装了Perl模块进入非标准目录,我们不得不让Perl知道去哪里搜索这四个目录。有两个实现方法:你
可以设置PERL5LIB 环境变量或者你可以在你的脚本中修改@INC变量。

假设我们用Perl 5.00503版本,在我们的例子中目录如下:

/home/sbekman/lib/perl5/5.00503/i386-linux
/home/sbekman/lib/perl5/5.00503
/home/sbekman/lib/perl5/site_perl/5.005/i386-linux
/home/sbekman/lib/perl5/site_perl/5.005

就象前面提到的,你能通过perl -V找到确切的目录并用你自己的私人目录代替全局的perl安装基目录。

修改 @INC 是很容易的。最好的途径是用lib模块(编译指示), 通过在你的脚本最上方加入以下代码片段,这些代码需要本地化已经安装的模块:

use lib qw(/home/stas/lib/perl5/5.00503/
/home/stas/lib/perl5/site_perl/5.005);

另一个途径是写代码显式修改@INC:

BEGIN {
unshift @INC,
qw(/home/stas/lib/perl5/5.00503
/home/stas/lib/perl5/5.00503/i386-linux
/home/stas/lib/perl5/site_perl/5.005
/home/stas/lib/perl5/site_perl/5.005/i386-linux);
}

注意既然它们如果存在会自动加入(确切地说,当$dir/$archname/auto存在的时候),那么用lib模块我们不必列出
一致的结构指定目录。

而且,注意到两种途径都预先考虑到@INC里被搜索的目录。这就允许你安装一个更新的模块加入你的本地库。Perl会用
这个模块取代已经安装在系统库里的旧模块。

两种途径都是在编译期间修改 @INC 的值。这个lib模块也用BEGIN块,但是是内部地。

现在,让我假设如下情景。我已经在我的本地库中安装了 LWP 包. 现在我想安装另一个模块(例如 mod_perl) ,这个模块
有在它的首选列表中列出的 LWP。我知道我已经安装 LWP ,但是当我为了准备安装的模块运行perl Makefile.pl,我被告知
我没有安装LWP。

Perl没有办法知道我们有本地已经安装的模块。所有这些都在@INC里列出的目录搜索中。既然后者包含只有4个缺省目录(加上
.目录),那么它不可能找到本地安装的 LWP 包。我们不能通过加入代码修改@INC来解决这个问题,而要改变PERL5LIB环境变量
才能解决。如果你正在用tcsh解决交互工作,那么这样做:

setenv PERL5LIB /home/stas/lib/perl5/5.00503:
/home/stas/lib/perl5/site_perl/5.005

它应该是带目录的单行,并且目录是被冒号(:)和非空格所分开。如果你是bash用户,那么这么做:

export PERL5LIB=/home/stas/lib/perl5/5.00503:
/home/stas/lib/perl5/site_perl/5.005

同样,写成单行。如果你用bash,那么你能通过反斜杆(\)来输入多行命令,象这样:

export PERL5LIB=/home/stas/lib/perl5/5.00503:\
/home/stas/lib/perl5/site_perl/5.005

由于用lib,所以如果存在,Perl自动会预先考虑结构指定目录到 @INC .

当我们这么做的时候,我们就要象以前那样通过执行perl -V来确认@INC新配置的值。你应该看到 @INC 修改的值:

% perl -V

Characteristics of this binary (from libperl):
Built under linux
Compiled at Apr 6 1999 23:34:07
%ENV:
PERL5LIB=”/home/stas/lib/perl5/5.00503:
/home/stas/lib/perl5/site_perl/5.005”
@INC:
/home/stas/lib/perl5/5.00503/i386-linux
/home/stas/lib/perl5/5.00503
/home/stas/lib/perl5/site_perl/5.005/i386-linux
/home/stas/lib/perl5/site_perl/5.005
/usr/lib/perl5/5.00503/i386-linux
/usr/lib/perl5/5.00503
/usr/lib/perl5/site_perl/5.005/i386-linux
/usr/lib/perl5/site_perl/5.005
.

当一切都如你所愿的那样工作时,加入这些命令到 .tcshrc 或者 .bashrc 文件. 当下次你启动shell的时候,环境将
会为你准备好与新的Perl一起工作。

注意,如果你设置了 PERL5LIB , 那么你不必在你的脚本中改变 @INC 的值。但是如果, 举例说, 其他人 (不想在
shell中设置的人)想执行你的脚本,那么Perl就不能找到你本地安装的模块。最好的例子就是 crontab 脚本,可以用
不同的SHELL环境,因此,不能进行PERL5LIB的设置。

于是最好的途径就是象上面所描述的,既设置PERL5LIB环境变量又在脚本开头修改 @INC 扩展代码。

CPAN.pm Shell 和 本地安装模块

CPAN.pm shell 在处理perl模块安装和保持更新的时候保存了大量的时间。它为我们做了这项工作,尽管在首选列表中检查到的丢失模块,
取出它们并安装。所以你会想知道你是否能用 CPAN.pm 也来保持你的本地库。

当你开始启动 CPAN 交互Shell的时候, 它会首先搜索用户私人配置文件和系统文件。当我作为stas用户被记录时,安装的两个文件会是:

/home/stas/.cpan/CPAN/MyConfig.pm
/usr/lib/perl5/5.00503/CPAN/Config.pm

如果你的系统没有 CPAN Shell,那么当你第一次启动shell时,它会问你一系列问题,然后为你建立Config.pm文件。

如果你已经有一个系统配置,那么你应该有/usr/lib/perl5/5.00503/CPAN/Config.pm. 如果你有不同版本的Perl,那么在找文件的
时候修改路径用你的Perl的版本号。新建目录(mkdir -p 立刻新建整个路径),该目录就是本地配置文件将放的地方:

% mkdir -p /home/stas/.cpan/CPAN

现在复制哈系统配置文件到本地。

% cp /usr/lib/perl5/5.00503/CPAN/Config.pm \
/home/stas/.cpan/CPAN/MyConfig.pm

唯一留下的事情是在你的本地文件改变 .cpan 基目录到你的私人目录下。在我的机器里,我用 /home/stas 取代 /usr/src/.cpan
(这就是我的 .cpan 系统目录所在地方)。我当然用perl!

% perl -pi -e ’s|/usr/src|/home/stas|’ \
/home/stas/.cpan/CPAN/MyConfig.pm

现在你已经有本地配置文件。当执行 perl Makefile.PL 的时候,你可以告诉它你必须传递什么参数。

用你最喜欢的编辑器打开该文件并替换下行:

‘makepl_arg’ => q[],

采用:

‘makepl_arg’ => q[PREFIX=/home/stas],

现在你已经完成了配置。假设你作为同样的用户登陆并准备好了本地安装(我们的例子是 stas),象这样开始:

% perl -MCPAN -e shell

从现在起,任何你想安装的模块都会被本地化安装。如果你必须安装一些系统模块,那么就成为超级用户并用同样的方法进行安装。当你
以超级用户登陆时,系统配置文件将被用而不是本地的。

如果你已经用了不只一个PREFIX变量,然后修改 MyConfig.pm 去用他们. 例如,如果你用这些变量:

perl Makefile.PL PREFIX=/home/stas \
INSTALLPRIVLIB=/home/stas/lib/perl5 \
INSTALLSCRIPT=/home/stas/bin \
INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
INSTALLBIN=/home/stas/bin \
INSTALLMAN1DIR=/home/stas/lib/perl5/man \
INSTALLMAN3DIR=/home/stas/lib/perl5/man3

在下面一行中用以上所有变量替换 PREFIX=/home/stas :

‘makepl_arg’ => q[PREFIX=/home/stas] 

于是该行变成:

‘makepl_arg’ => q[PREFIX=/home/stas \
INSTALLPRIVLIB=/home/stas/lib/perl5 \
INSTALLSCRIPT=/home/stas/bin \
INSTALLSITELIB=/home/stas/lib/perl5/site_perl \
INSTALLBIN=/home/stas/bin \
INSTALLMAN1DIR=/home/stas/lib/perl5/man \
INSTALLMAN3DIR=/home/stas/lib/perl5/man3],

如果你能在一行内放置所有以上参数,那么你可以去掉反斜杆 (\).

安装本地 Apache

就像 Perl 模块一样, 如果你没有权限安装文件到系统区,那么你不得不本地化安装它们到你的私人目录。这几乎跟简单安装一样,
但是你不得不运行侦听端口号大于1024的服务器,因为只有root进程才能侦听小于1024的端口号。

另一个重要的问题你必须解决的是如何把启动关闭脚本作为系统服务写入目录里。你将不得不向你的系统管理员寻求帮助。

为了本地化安装Apache, 所有你必须做的是告诉Apache源代码目录里的.configure文件应该用那些目的目录。如果你
按照我的约定使你的私人目录看起来象 / 根目录一样,那么期望的参数将是:

./configure—prefix=/home/stas

Apache 会用前缀来代替目的目录其余部分,而不是缺省的 /usr/local/apache. 如果你想知道它们是什么,那么运行之前
加上—show-layout 选项:

./configure—prefix=/home/stas—show-layout

你可能想按照Apache的约定把Apache所有的文件放在 /home/stas/apache 下:

./configure—prefix=/home/stas/apache

如果你想修改一些或者所有自动创建的目录的名字:

./configure—prefix=/home/stas/apache \
—sbindir=/home/stas/apache/sbin
—sysconfdir=/home/stas/apache/etc
—localstatedir=/home/stas/apache/var \
—runtimedir=/home/stas/apache/var/run \
—logfiledir=/home/stas/apache/var/logs \
—proxycachedir=/home/stas/apache/var/proxy

就这些!

而且记住你只能在属于你的用户和用户组下运行该脚本。 你必须在httpd.conf里设置合适的值给用户和组项。

手动安装本地 mod_perl 启用 Apache

既然我们知道如何分开安装Apache和Perl模块,那就让我们来看看如何在我们的私人目录安装mod_perl启用Apache。这几乎跟分开
安装一样简单,但是有一个问题你需要知道的,这在本部分的最后我会提到。

假设你解包 Apache 和 mod_perl 源代码到 /home/stas/src 目录下,就像这样:

% ls /home/stas/src
/home/stas/src/apache_x.x.x
/home/stas/src/mod_perl-x.xx

这里的 x.xx 是跟以前一样的版本号。你想从已安装在 /home/stas/lib/perl5 下的 mod_perl 包中得到Perl模块和 /home/stas/apache
目录下的 Apache 文件。以下命令是这么做的:

% perl Makefile.PL \
PREFIX=/home/stas \
APACHE_PREFIX=/home/stas/apache \
APACHE_SRC=../apache_x.x.x/src \
DO_HTTPD=1 \
USE_APACI=1 \
EVERYTHING=1
% make && make test && make install
% cd ../apache_x.x.x
% make install

如果你需要一些参数传递给 .configure 脚本, 就像我们在以前的章节里看到的,那么就用 APACI_ARGS. 例如:

APACI_ARGS=’—sbindir=/home/stas/apache/sbin, \
—sysconfdir=/home/stas/apache/etc, \
—localstatedir=/home/stas/apache/var, \
—runtimedir=/home/stas/apache/var/run, \
—logfiledir=/home/stas/apache/var/logs, \
—proxycachedir=/home/stas/apache/var/proxy’

注意以上多行分开只工作在bash下, tcsh用户将不得不在同一行列出所有参数。

基本上安装结束。唯一留下的问题是 @INC 变量。如果你依赖 PERL5LIB 环境变量,那么@INC 将不会被正确设置,除非
你在你的启动文件中显式设置它。启动文件必须在装载任何你的本地库模块之前启动。一个更好的途径就像我们以前
看到的,是用lib编译指示,但是稍微有点不同的地方:我们在启动文件中用这种方法将会影响所有在mod_perl处理下的代
码将会被执行。例如: PerlRequire /home/stas/apache/perl/startup.pl
这里的 startup.pl 以这样开始:

use lib qw(/home/stas/lib/perl5/5.00503/
/home/stas/lib/perl5/site_perl/5.005);

注意你仍可以在脚本中用硬编码的 @INC 的修改, 但意识到脚本修改BEGIN块里的 @INC, 而mod_perl 只在脚本编译的时候
才执行 BEGIN块。结果,@INC 将会在编译以后被原始值复位,硬编码的设置将会被遗忘。

只有一个地方你可以改变“原始”值是在启动文件或者放

PerlSetEnv Perl5LIB \
/home/stas/lib/perl5/5.00503/:/home/stas/lib/perl5/site_perl/5.005

到 httpd.conf的服务器配置阶段, 但是后者设置如果你用 PerlTanintcheck 设置将会被忽略。我希望你能这样用它。

接下来的mod_perl 配置和使用是一样的,就好像你正在以超级用户身份安装mod_perl一样。

用 CPAN.pm 进行本地安装 mod_perl 启用 Apache
假设你已经像文章前面所解释的配置 CPAN.pm 来安装Perl模块,那么安装就简单了。

启动 CPAN.pm shell, 设置参数传递给 perl Makefile.PL (修改例子设置适合你的需要), 然后告诉 为你去做剩下的事:

% perl -MCPAN -eshell
cpan> o conf makepl_arg ‘DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 \
PREFIX=/home/stas APACHE_PREFIX=/home/stas/apache’
cpan> install mod_perl

当你为了本地化安装用 CPAN.pm 的时候, mod_perl 安装结束之后你必须确认 makepl_arg 是否被回复到原始值。最简单的方法是通过输入
quit退出交互Shell然后重新输入。但是如果要坚持,那么下面就是如果不退出Shell就生效. 你真的想跳过这个:)

如果你想不退出Shell用CPAN继续工作,那么你必须:

1)记住 makepl_arg 的值

2)改变它以适合你的新安装

3)构建和安装 mod_perl

4)安装 mod_perl 之后恢复它

这是相当麻烦的任务,但是我相信 CPAN.pm 最终会被改善,处理起来更容易。

所以你还是跟我一起,那么就像通常一样启动 Shell:

% perl -MCPAN -eshell

第一,读取 makepl_arg 的值:

cpan> o conf makepl_arg
PREFIX=/home/stas

如果你配置CPAN.pm来本地化安装模块,那就会是象 PREFIX=/home/stas 这样的字符串。保存这个值:

cpan> o conf makepl_arg.save PREFIX=/home/stas

第二,设置一个新值, mod_perl 安装进程会用到它。(你可以根据你的需要加入参数到这行或者删除)

cpan> o conf makepl_arg ‘DO_HTTPD=1 USE_APACI=1 EVERYTHING=1 \
PREFIX=/home/stas APACHE_PREFIX=/home/stas/apache’

第三, 让 为你构建和安装 mod_perl:

cpan> install mod_perl

第四, 复位makepl_arg到原始值.我们可以通过打印这些保存的变量值然后分配给 makepl_arg来实现.

cpan> o conf makepl_arg.save
PREFIX=/home/stas
cpan> o conf makepl_arg PREFIX=/home/stas

不是很简明,但却是一个有效方法。你可以在一张纸条上写下这个值,而不是保存在 makepl_arg.save, 但是这样你更可能犯错误。

参考

Apache 网站网址: http://www.apache.org

mod_perl 网站网址: http://perl.apache.org

CPAN 是 Perl 综合典藏网的缩写(Comprehensive Perl Archive Network). 主站网址是http://cpan.org/.

世界范围内,CPAN 的镜像站点有 100 多个。(http://cpan.org/SITES.html)

在包含原始程式的目錄裡面,鍵入:

% ./configure
% make
% make POSTGRESDIR=PostgresTopDir install

如果你想把安裝組件放到不同的目錄樹中,那麼你可以顯式地聲明各種不同的目的地:

% make BINDIR=bindir  LIBDIR=libdir  HEADERDIR=headerdir ODBCINST=instfile install
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: