【问题标题】:Why can't my Perl script load a module when run by cron?为什么我的 Perl 脚本在 cron 运行时无法加载模块?
【发布时间】:2011-11-18 03:31:52
【问题描述】:

我有一堆运行良好的 Perl 脚本,但需要在顶部添加 use Plibdata;

我设置了一个运行的 cron 作业(我从 root 收到确认电子邮件),它返回以下错误消息:

Can't locate Plibdata.pm in @INC (@INC contains: /install/lib /opt/perl58/lib/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/5.8.8 /opt/perl58/lib/site_perl/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/site_perl/5.8.8 /opt/perl58/lib/site_perl .) at ./x line 5.

BEGIN failed--compilation aborted at ./x line 5.

第 5 行是……你猜对了……use Plibdata;

我也在尝试这样设置环境:

use lib "$ENV{CARSPATH}/install/lib";

所以如果我找到了这个 plibdata 的位置,我可以明确地指向它吗?

我的 cron 命令将使用 /usr/bin/sh 执行,如 crontabs...

有什么建议吗?

此脚本可从命令行运行。

【问题讨论】:

    标签: perl cron


    【解决方案1】:

    你没有说 Plibdata 是什么。您也没有说明这是否适用于您的命令提示符。我认为确实如此。

    试试这个:

    perl -MPlibdata -e 1
    

    假设没有出现同样的错误,试试这个:

    perl -MPlibdata -le 'print $INC{"Plibdata.pm"}'
    

    这会告诉你在哪里。 (如果可行,它可能在您的 PERL5LIB 环境变量中。)然后您可以将适当的“使用库”添加到 Plibdata.pm 所在的目录中。

    另外,请确保您在两个位置都使用相同的 perl - 命令行(“which perl”)和 cron 作业(尝试脚本顶部的“BEGIN { print $^X }”)。

    【讨论】:

    • 这两个都给了我上面提到的同样的错误信息
    • 好的,那么 $CARSPATH 包含什么?在命令行中“回显 $CARSPATH”。如果这没有显示任何内容,那么您需要与您的开发人员同事讨论它的真实位置。
    • 还有 /opt/carsi/install/lib/Plibdata.pm 吗?您要么必须使用 lib "/opt/carsi/install/lib";,要么使用 lib "$ENV{CARSPATH}/install/lib";并找到一种方法在您的 crontab 或其他东西中设置 CARSPATH(这将成为一个新问题)。
    • 是的,我使用的是确切的语法.. 第二个...我试试第一个版本(基本上相同,但更明确)感谢所有帮助
    • 哦,是的 /opt/carsi/install/lib/Plibdata.pm 存在
    【解决方案2】:

    Cron 登录时使用的用户 env 与您的 env 不同。您可以从命令行运行脚本吗?如果是这样,只需在当前命令上方的 cron 中设置环境变量。

    【讨论】:

    • 这个问题似乎表明它们是从命令行运行的。我很确定您没有设置环境变量是正确的。
    • 我该怎么做呢?在 cron.txt 里面?
    【解决方案3】:

    显然,Plibdata.pm 没有安装在系统的默认模块路径中:

    /install/lib /opt/perl58/lib/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/5.8.8 /opt/perl58/lib/site_perl/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/site_perl/5.8.8 /opt/perl58/lib/site_perl
    

    你有三个选择:

    1. 在已知的 Perl 系统路径中安装 Plibdata.pmsite_perl 是经典选项)。

    2. 使 PERL5LIB shell 环境(或 Perl 的等效命令行 -I 选项)包含模块的安装路径。

    3. 在您的脚本中使用use lib。请记住,use lib 操作是在编译时完成的,因此路径中的变量可能未初始化。尝试在 BEGIN 块中使用变量,如下所示:

      my $env;
      
      BEGIN {
        $env = $ENV{CARSPATH};
      }
      
      use lib "$env/install/lib";
      

    【讨论】:

    • 只有数字 1 有效。他/她正在cron下运行代码,因此没有环境
    • 我想我已经在这样做了..... use lib "$ENV{CARSPATH}/install/lib";也在使用块中
    • CheeseConQueso:重要的部分是 BEGIN 块。这在编译时而不是在运行时执行。这两个步骤都在您运行 perl 时发生,但按照经典的严格顺序:编译->运行。 nxadm
    【解决方案4】:

    按照其他人的建议从包装脚本运行程序可能是我的首选方法,但可能还有其他一些解决方案:

    如果您使用的是现代 cron,则可以在您的 crontab 条目中执行以下操作:

    * * * * * CARSPATH=/opt/carsi x
    

    将星号替换为适当的日程指示符。

    这将为 x 进程设置 CARSPATH 并允许传递环境变量的 use lib 语句工作。

    您还可以根据您的 shell 和 cron 实现,将您的环境设置存储在一个文件中并执行以下操作:

    * * * * * source specialenv.sh && x
    

    其中 specialenv.sh 包含类似 (for bash) 的行

    export CARSPATH=/opt/carsi
    

    如果您选择这样做,您也可以直接在 crontab 中设置环境变量。

    【讨论】:

    • * * * * * CARSPATH=/opt/carsi x 为了胜利!!
    【解决方案5】:

    cron 在运行您的代码时不会为您设置环境,因此环境变量$CARSPATH 不存在。我建议只从 cron 运行 shell 脚本,在 shell 脚本中设置环境,然后运行你真正想要运行的程序。

    示例包装脚本:

    #!/bin/bash
    
    source ~username/.bash_profile
    cd ~username
    ./script.pl
    

    如果您使用的是kshsh,您可能需要说明

    #!/bin/sh
    
    . ~username/.profile
    cd ~username
    ./script.pl
    

    请记住将用户名替换为您在系统上的用户名。此外,如果脚本不在您的主目录中,您将希望使用它的路径执行它,而不是 ./

    您说source 或句点空间,以在当前shell 中加载给定的shell 脚本。您将其加载到当前 shell 中,以便任何环境设置都保留在当前 shell 中。

    ~/.bash_profile~/.bashrc~/.profile/etc/profile 等都是通常保存您的环境设置的文件。您使用哪一个在很大程度上取决于您的操作系统和设置它的人。

    【讨论】:

    • 如何在 shell 脚本中设置环境? #!/bin/ksh ?
    • 它不会从命令行运行.....解释器“/bin/bash”找不到文件链接解析为“/usr/bin/bash”...... . 可以用#!/bin/ksh 完成吗?
    • 我尝试了几种不同的组合....看来我需要 bash 而不是 ksh 源 ~CheeseConQueso/.bash_profile 才能工作... ksh 忽略它,吐出一个错误,然后运行脚本正常.. 我试过 .ksh_profile - 也没有运气
    • 可以,但是将“source”改为“.”和“.bash_profile”到“.profile”。这也假设 CheeseConQueso(带有该大小写)是您在该系统上的用户名。
    • 它还假设脚本在您的主目录中,您可能需要更改路径。
    【解决方案6】:

    虽然它不是一个“答案”,但我通过使用 DBI 而不是 Plibdata 解决了这个问题。

    这有点像牛奶,因为现在我将不得不更改几个脚本...啊啊啊我希望我可以做些什么来使 Plibdata 工作

    我还是要试试查斯。欧文斯回答看看是否有效


    对我不起作用...“未找到解释器“/bin/bash””
    也许它适用于拥有该解释器的人



    * * * * * CARSPATH=/opt/carsi ./x
    

    作品

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-15
      • 1970-01-01
      • 2011-01-18
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多