【问题标题】:Running a Perl script from crontab when you use Perlbrew使用 Perlbrew 时从 crontab 运行 Perl 脚本
【发布时间】:2018-05-07 13:22:41
【问题描述】:

我尝试了以下方法并发现它可以工作。这是由非特权用户完成的。首先找出你的 perl 命令在哪里:

# which perl

然后检查PERL5LIB的值:

# echo $PERL5LIB

然后,在用户的 crontab 文件中,执行以下操作:

MAILTO=<my email address for the jobs output>
HOME=/home/myhome
PERL5LIB=/home/myhome/perl5/lib/perl5

0 2 * * * $HOME/<rest of path to perl>/perl $HOME/<path to my perl script> arg1 ...

这将在凌晨 2 点运行作业,并且似乎可以正确找到所有 Perl 库。我的问题是:这是否完整且便携?有没有更好的办法?

我已经看到了许多 bashperl 脚本,它们应该为执行 Perl 脚本准备环境,但这似乎就足够了。欢迎任何建议!

编辑:从 cmets 到问题,似乎我正在使用 Perlbrew 和 local::lib 的“坏”混合物。确保在特定 Perlbrew 版本中安装库的方法在这里得到解答:How do I install CPAN modules while using perlbrew?。当您使用local::lib 时,cpancpanm 都将安装在PERL5LIB 下,除非您明确告诉他们不这样做。此外,cpanm 似乎更适合与 Perlbrew 一起工作。

【问题讨论】:

  • 查看并阅读有关Ubic 的信息。对于您的用例来说,这肯定是一种矫枉过正,但您可以得到一些想法......
  • 你应该能够运行类似 `bash 'perlbrew use perl-5.28.0; perl $HOME/' 来自 cron。这将为该子 shell 选择一个特定的 Perl 并自动设置所有内容。
  • @simbabque 除了 perlbrew use 似乎执行到一个新的 shell 中,所以你需要将命令输入它:perlbrew use perl-5.26 &lt;&lt;&lt;'perl ./some-script.pl'(Bash 语法)。 perlbrew exec --with perl-5.26 'perl ./some-script.pl' 是等价的,但在输出之前会打印一个烦人的标题。
  • 将 local::lib 与 perlbrew 一起使用没有多大意义,因此您不应该设置 PERL5LIB
  • @amon, Re“除了 perlbrew 使用似乎执行到一个新的 shell,”,如果你有 perlbrew 正确设置,则不是。在 shell 启动时有一个文件需要为 sourced。您正在描述未完成时的备份行为。

标签: perl cron perlbrew


【解决方案1】:

如果您已经有多个使用perlbrew 管理的 perl 安装,最简单的方法是使用perlbrew exec 来运行您的脚本。 -q--with 选项允许您关闭多余的输出并选择特定版本的 perl 来运行脚本/作业。尝试类似:

  • perlbrew exec perl -E 'say "Hello from $]\n"'(这将显示旧版本的 perl (&lt; 5.10) 中没有默认启用 -E 开关的错误)。
  • perlbrew exec -q --with 5.26.1 perl -E 'say "Hello from $]\n"'(这将运行命令并抑制信息输出)。
  • perlbrew exec -q --with 5.26.1 perl ~/script_from_heaven.pl(使用请求的 perl 版本运行脚本)。
  • perlbrew exec -q --with 5.26.1 ~/script_from_heaven.pl(在脚本的 shebang 行中使用请求或硬编码的 perl 版本运行脚本)。

我倾向于显式设置PERL5LIB 并使用local::lib 当我需要它们时,或者对于我在@中专门安装所有 CPAN模块的某些用户或环境987654336@(比如说一个完整的应用程序部署)。否则我发现从perlbrew 运行 perl 非常方便。


我发现有几件事很有帮助:为 perlbrew 环境设置一个 alias 以使其在特定用途中保持稳定可能是管理多个 perls 的有用方法:

 ~/$ perlbrew alias create perl-5.24.0 stable-cronperl
 ~/$ perlbrew list
 perl-5.8.9
 perl-5.10.1
 perl-5.24.0
 cperl-cperl-5.26.1
 stable-cronperl (5.24.0)
 perl-5.26.1

注意:但是,如果您想让脚本可执行,则别名仅可用作稳定的#! shebang 锚点,以便在脚本顶部使用:

#!/home/cronic/perl5/perlbrew/perls/stable-cronperl/bin/perl

您不能使用--with 引用别名,例如:

perlbrew exec --with stable-cronperl ~/smart_comments.pl

将此作为文档问题或错误报告在我的待办事项列表中。

【讨论】:

  • 还有 Tokuhirom 的plenv ;-) Miyagawa 一直在给plenv 添加“缺失”的perlbrew 命令:github.com/miyagawa/plenv-contrib
  • 我发现你的答案更完整,但 ikegami 更正确。所以我会标记他的正确,但给你我的赞成票。
【解决方案2】:

脚本的 shebang (#!) 行应该指向 (perlbrew-installed) perl 它打算在其下运行。 (这应该作为安装脚本的一部分完成。)这就是您所需要的。

0 2 * * * /path/to/script arg1 ...

【讨论】:

  • ++ 这正是 Gugod 在删除“当前”符号链接后引入 alias 功能的原因。见:github.com/gugod/App-perlbrew/issues/142
  • 我假设您可以使用 regular shebang 并从 crontab0 2 * * * /path/to/perl /path/to/script arg1 ... 调用正确的 Perl 解释器。这将使您可以移动脚本,而无需对它需要的 Perl 解释器进行硬编码。我说的对吗?
  • 是的,你可以在 cron 作业中硬编码它,你可以在其他任何地方使用它,但这很糟糕!!!当您安装它时,它应该在脚本中进行硬编码。这样,该脚本仅与测试和安装它的perl 一起使用。标准的 Perl 安装程序甚至会自动为您将#!/usr/bin/perl 重写为正确的路径。它使您免于在一百万个位置(例如 cron 文件)中对其进行硬编码,或者免于使用不是为它设置的安装。我坚持我的答案。
  • @ikegami,非常感谢您的解释!这很有道理。我的疑虑来自于我倾向于以与版本无关的方式在 Perl 中编写代码。可能是因为我倾向于在 cPanel 管理的机器中使用系统的 Perl 解释器,随着时间的推移会改变它..
  • 我不知道你为什么认为那是不同的。您使用系统perl 的脚本不是将#!/usr/bin/perl 作为第一行吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 2017-08-31
相关资源
最近更新 更多