【问题标题】:Perl script does not output STDOUT to file when run from cron从 cron 运行时,Perl 脚本不会将 STDOUT 输出到文件
【发布时间】:2018-06-04 04:07:18
【问题描述】:

对 Perl 相当陌生。 我在 Linux 机器上有一个 Perl 脚本,它有自己的日志文件。日志文件名称可以更改,具体取决于脚本正在处理的数据(日期、文件名、数据类型等)

某些节点的脚本正在使用 system() 调用调用本机可执行文件,这会将一些信息提供给 STDOUT 和 STDERR - 在几分钟内几十到几百行。可执行文件完成后,脚本继续并将一些其他信息记录到日志文件中。

到目前为止,脚本只记录了它自己的输出,没有本机可执行文件输出,我想登录与 Perl 脚本登录的相同文件。尝试了以下两种方法:

#!/usr/bin/perl
#some other code
@array_executable_and_parameters = qw/echo foo/ ;
open $log_fh, '>>', 'log/logfile1.txt';
*STDOUT = $log_fh;
*STDERR = $log_fh;
print "log_fh=$log_fh\n";
system( @array_executable_and_parameters);

$logfilename='log/logfile2.txt';
open(LOGFILEHANDLE, ">>$logfilename" );
*STDOUT = LOGFILEHANDLE;
*STDERR = LOGFILEHANDLE;
print LOGFILEHANDLE "Somethinglogged\n";
system( @array_executable_and_parameters);

它在我手动运行脚本时有效,但在从 cron 运行时无效。

我知道可以通过 Linux 方式在 crontab 中重定向,但是我必须知道要登录的文件名,只有在一些数据到达时才会知道,所以在我看来是不可行的。我也希望尽可能多地包含在脚本中,而不需要对 Linux 等有太多依赖。我也无法安装任何额外的模块、Perl 使用的库,假设它是最低限度的安装。

如何从 Perl 脚本中将 STDOUT 和 STDERR 重定向到特定文件?

如果可能,我如何检测 STDOUT 当前所在的文件名?

【问题讨论】:

  • 这个 Perl 脚本是如何被调用的,你是如何调用system()的?
  • 来自 crontab:* * * * * /home/username/perl/myscript.pl 手动:./home/username/perl/myscript.pl 从脚本内部调用可执行文件,例如:system( @array_executable_and_parameters);
  • 您的交互式示例在/home 之前有一个点,因此除非您在根目录中,否则它们是不等价的;但我认为这是一个虚假的细节。您能否在演示脚本中通过简单的system() 调用来edit 提出您的问题,但未能达到您的预期?
  • 感谢您的编辑,我们仍然需要一个很好的例子来说明数组中的内容,以使其成为正确的minimal reproducible example

标签: linux perl cron stdout


【解决方案1】:

重新分配 *STDOUT 只会影响 Perl 内部的 STDOUT 标量绑定。在系统级别重定向标准输出的正确方法类似于

open (STDOUT, '>&', $log_fh) or die "$0: could not: $!";

您应该同样报告其他可能失败的系统调用的错误(以及use strict 等)。

cron 在您的主目录中运行您的作业,因此如果路径 $HOME/log 不存在,脚本将无法打开日志文件句柄(静默,因为您没有记录 open 错误!)

【讨论】:

  • select 呢?
  • 没有具体测试过,但是是的,TMTOWTDI。
  • @simbabque, select 也不会影响system。只有open (STDOUT, '>&', $log_fh)open (STDOUT, '>', "...") 会改变fd 1
  • open(LOGFILEHANDLE, ">>$logfilename" ); 之后添加open (STDOUT, '>>', "$logfilename"); 工作方式相同 - 手动运行时一切正常,但从 cron 运行时将所有内容输出到邮件文件。我不能使用严格的,因为脚本是失败的老和大野兽,很多地方需要一些改进。我可能完全不知道还有一些遗漏的东西,感谢您在这里对 Perl 初学者的耐心:)
  • 所以,重复;您是在log 目录所在的目录中从cron 运行它,并且您确定您能够成功打开日志文件吗?
猜你喜欢
  • 2018-06-17
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 2017-01-23
  • 2015-05-21
  • 2012-12-08
  • 1970-01-01
相关资源
最近更新 更多