无需超级用户权限安装mod_perl

正如您从前面的文章中看到的那样,mod_perl使得Apache包含两个主要组件:Perl模块和Apache本身。虽然无需root权限安装Apache很简单,但您应该知道如何在一个非系统范围内安装Perl模块。在这篇文章中,我将演示如何完成这项任务。

在示例中,我将使用stas作为用户名,并使用/home/stas作为该用户的家目录。

将Perl模块安装到指定目录中

由于没有超级用户权限,您不能将模块安装到系统目录,例如/usr/lib/perl5,因此您需要找出如何在您的家目录下安装模块。这很简单。

首先,您必须决定在哪里安装模块。最简单的方法是在您的家目录下模拟与Perl相关的/文件系统的部分。实际上我们只需要两个目录

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

我们不需要创建它们,因为当安装第一个模块时,它们会自动创建。99%的文件将放入lib目录。偶尔,当某些模块分布包含Perl脚本时,这些脚本将放入bin目录。如果该目录不存在,它将被创建。

让我们安装包含一些其他CGI::*模块的CGI.pm包。像往常一样,从CPAN存储库下载该包,解包,并使用chdir转到新创建的目录。

现在执行标准的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将所有文件安装到私有存储库中。请注意,所有缺失的目录都将自动创建,因此不需要创建它们。下面(略有编辑)是它所做的事情

  Installing /home/stas/lib/perl5/CGI/Cookie.pm
  Installing /home/stas/lib/perl5/CGI.pm
  Installing /home/stas/lib/perl5/man3/CGI.3
  Installing /home/stas/lib/perl5/man3/CGI::Cookie.3
  Writing /home/stas/lib/perl5/auto/CGI/.packlist
  Appending installation info to /home/stas/lib/perl5/perllocal.pod

如果您必须使用显式的目标参数,那么您将找到创建一个名为,例如,~/.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模块存储库。例如,您可以为生产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 shell中用于查找可执行程序的PATH环境变量等效。

请注意,Perl也在.目录中查找模块,它代表当前目录。它是上述输出的最后一个条目。

当然,这个例子来自安装在我的基于x86架构的Linux PC上Perl 5.00503 版本。这就是为什么你会看到i386-linux5.00503。如果你的系统运行的是不同版本的Perl、操作系统、处理器或芯片组架构,那么一些目录将具有不同的名称。

我还在/usr/local/lib/下安装了perl-5.6.1,所以当我做

  % /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

系列中的之前内容

30分钟学会mod_perl

为什么是mod_perl?

请注意,它仍然是Linux,但较新的Perl版本使用我的Pentium处理器的版本(因此是i586而不是i386)。这允许在创建二进制Perl扩展时利用Pentium处理器的编译器优化。

所有平台特定的文件,例如使用XSSWIG将编译的C文件粘接到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模块(pragma)。

  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);
        }

请注意,使用lib模块时,我们不需要列出相应的架构特定目录,因为它会自动添加它们(更确切地说,当$dir/$archname/auto存在时)。

此外,请注意,两种方法都将要搜索的目录prepend@INC中。这允许您将较新的模块安装到本地存储库中,Perl将使用它而不是在主系统存储库中安装的较旧的模块。

两种方法都在编译时修改了@INC的值。lib模块还使用BEGIN块,但内部使用。

现在,让我们假设以下场景。我已经在我的本地存储库中安装了LWP包。现在我想安装另一个模块(例如,mod_perl),该模块在其依赖列表中列出了LWP。我知道我安装了LWP,但当我为要安装的模块运行perl Makefile.PL时,我被告知我没有安装LWP

Perl无法知道我们有一些本地安装的模块。它所做的只是搜索列在@INC中的目录,而后者只包含默认的四个目录(加上.目录),因此它无法找到本地安装的LWP包。我们无法通过添加代码来修改@INC来解决这个问题,但通过更改PERL5LIB环境变量就可以做到这一点。如果您使用t?csh进行交互式工作,那么这样做

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

应该是一行,目录用冒号(:)分隔,没有空格。如果您是(ba)?sh用户,那么这样做

  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

use lib一样,如果存在,Perl会自动将架构特定目录prepend@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 将无法找到您本地安装的模块。最好的例子是可能使用不同 SHELL 环境的 crontab 脚本,因此 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进程可以监听低序号端口。

您必须解决另一个重要问题,那就是如何将启动和关闭脚本添加到其他系统服务使用的目录中。您将不得不请求系统管理员帮助您解决这个问题。

要在本地安装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中设置UserGroup指令为适当的值。

手动本地启用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是版本号。您希望mod_perl包中的Perl模块安装到/home/stas/lib/perl5下,Apache文件放到/home/stas/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'

请注意,上面的多行拆分仅在bashtcsh用户中有效,tcsh用户必须将所有参数放在一行上。

基本上,安装已经完成。唯一剩下的问题是@INC变量。如果您依赖于PERL5LIB环境变量,除非您在启动文件中明确设置它,否则它将不会正确设置。一种更好的方法是使用我们在前面看到的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中,但如果您使用PerlTaintcheck设置,则此设置将被忽略,我希望您确实使用了它。

mod_perl的配置和使用与其他情况相同,就像您以超级用户身份安装mod_perl一样。

使用CPAN.pm的本地mod_perl启用Apache安装

假设您已经按照本文前面所述配置了CPAN.pm以本地安装Perl模块,安装过程很简单。启动CPAN.pmshell,设置要传递给perl Makefile.PL的参数(根据您的需求修改示例设置),并告诉<CPAN.pm>为您完成剩余工作

  % 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,那么您必须

系列中的之前内容

30分钟学会mod_perl

为什么是mod_perl?

  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'

第三,让<CPAN.pm>为您构建和安装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,但您更有可能出错。

参考资料

标签

反馈

这篇文章有什么问题吗?通过在GitHub上打开问题或拉取请求来帮助我们。