【问题标题】:Perl code doesn't run in a bash script with scheduling of crontabPerl 代码不能在 bash 脚本中运行,并安排了 crontab
【发布时间】:2020-12-19 14:18:43
【问题描述】:

我想安排我的 Perl 代码在每天的特定时间运行。所以我把下面的代码放在 bash 文件中:

Automate.sh

    #!/bin/sh
    perl /tmp/Taps/perl.pl

时间表已在以下路径中指定:

10 17 * * * sh /tmp/Taps/Automate.sh > /tmp/Taps/result.log

当时间到达 17:10 时,.sh 文件尚未运行。但是,当我(手动)运行 ./Automate.sh 时,它正在运行并且我看到了结果。不知道是什么问题。

Perl 代码

#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
use XML::Dumper;
use TAP3::Tap3edit;
$Data::Dumper::Indent=1;
$Data::Dumper::Useqq=1;
my $dump = new XML::Dumper;
use File::Basename;


my $perl='';
my $xml='';
my $tap3 = TAP3::Tap3edit->new();

   foreach my $file(glob '/tmp/Taps/X*')
   {
   $files= basename($file);
   $tap3->decode($files) || die $tap3->error;
    }

my $filename=$files.".xml\n";
$perl = $tap3->structure;
$dump->pl2xml($perl, $filename);
print "Done \n";

错误:

No such file or directory for file X94 at /tmp/Taps/perl.pl line 22.
X94.xml

【问题讨论】:

  • 我做到了,但它没有运行,我有一个空的日志文件
  • @Saher : cron 应该通过邮件向您发送标准错误。因此,您应该会收到一些错误消息。或者,您可以执行2>&1 并在您的result.log 中收集标准错误。我也会使用-xsh。然后,日志文件至少不能为空了。我会指定shperl 的完整路径。
  • 创建 crontab 作业,在其中放置命令 env > /tmp/env_data,一旦运行 cronjob,您将看到在 crontab 中设置的所有变量。 man crontab 提供了足够的信息来理解运行程序所需的设置。
  • 你为什么使用basename?考虑一下如果你的密码是 / 会发生什么
  • $files 未在您显示的代码中的任何位置声明。使用use strict,此代码将产生致命错误Global symbol "$files" requires explicit package

标签: bash shell perl cron


【解决方案1】:

这里有很多可能出错的地方。最明显和确定的是,如果您使用 glob 在目录“Taps”中查找文件,然后使用 basename 从文件名中删除该目录,则 Perl 无法找到该文件。不太确定你想在那里实现什么。来自 glob 的文件名将是例如 Taps/Xfoo,它是工作目录的相对路径。如果您尝试从工作目录访问Xfoo,将找不到该文件(或会找到错误的文件)。

这也应该(可能)导致致命错误,应该在您的错误日志中报告。 (假设decode 函数在出错时返回一个假值,这是不确定的。)如果您的错误日志中没有报告任何错误,则表明程序根本没有运行。或者可能是decode 没有在丢失文件时返回 false,并且文件被认为是空的。

我假设当你测试程序时,你 cd/tmp 并运行它,或者你的“Taps”目录在你的主目录中。因此,您正在假设您的程序在哪里查找文件。您应该确定它在哪里查找文件,可能只使用绝对路径。

另一个简单的错误可能是 crontab 没有执行文件的权限,或者没有对“Taps”的读取权限。

编辑:

代码中的其他复杂情况:

  • 您包含 Data::Dumper,但从未实际使用过该模块。
  • $xml 变量未使用。
  • $files 变量未声明(此代码永远不会与 use strict 一起运行)
  • 您的$files 变量在您的foreach 循环之外,这意味着它只会运行一次。由于您使用glob,我假设您正在阅读多个文件,在这种情况下,此解决方案可能无法满足您的需求。您也可能使用glob,因为文件名可以更改,例如X93X94 等。在这种情况下,您将读取 glob 返回的最后一个文件名。但这看起来是您逻辑中的一个薄弱环节。
  • 您在文件名中添加换行符\n,这很奇怪。

【讨论】:

  • 我尝试进行相关更改并修改代码。但我得到了如上所示的错误。
  • No such file or directory 错误可能是因为您在相对文件名上使用了basename,就像我解释的那样。
【解决方案2】:

foreach my $file(glob 'Taps/X*') -- 当你从 cron 运行时,你的当前目录是 /。您需要提供该 Taps 目录的完整路径。同时指定 Out.xml 的输出目录

【讨论】:

  • 我如上修改了我的代码,现在我得到了上面的错误:在 /tmp/Taps/perl.pl 第 22 行没有文件 X94 的此类文件或目录。X94.xml
【解决方案3】:

Cron 使用一个最小的环境和一个简短的$PATH,它可能不一定包含perl 的预期路径。尝试完全指定此路径。或者在运行脚本之前source 你的 shell 设置。

【讨论】:

  • crontab中指定的文件命名不完整?我使用了短路径,但结果没有改变!
  • 我的意思是使用 /path/to/perl 而不仅仅是 perl。
  • 我修改了我的代码并得到了上述错误。 /tmp/Taps/perl.pl 第 22 行中的文件 X94 没有这样的文件或目录。X94.xml
猜你喜欢
  • 1970-01-01
  • 2015-12-12
  • 2017-12-02
  • 2018-08-10
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
相关资源
最近更新 更多