AIX和Linux之间的Perl模块/使用和需要问题

时间:2014-02-06 15:11:03

标签: perl

我正在尝试使用脚本来获取否。从现在到未来的日期之间的几天。我打算从一个公共位置在AIX和Linux上运行这个脚本。现在,我使用模块DateTime用于linux,使用Date::Calc用于AIX。出于某种原因,每个都不适用于其他操作系统。 所以,我正在写一个if语句并检查操作系统。如果是AIX,我使用的是Date::Calc,或者我正在使用DateTime。这是我的代码

#!/usr/bin/perl
use strict;
use warnings;
my $OS = `uname`;
if ( $OS=~/AIX/i ) {
use Date::Calc qw(Delta_Days);
my @today = (localtime)[5,4,3];
$today[0] += 1900;
$today[1]++;
my @end = (2015, 11, 12);
my $expiry = Delta_Days(@today, @end);
print "$expiry\n";
} else {
require DateTime;
my $exp = DateTime->new( year => 2015, month => 11, day => 12 );
my $now = DateTime->now;
my $diff = $now->delta_days($exp);
my $expiry = $diff->delta_days;
print $expiry,"\n";}

当我在use Date::Calc循环中使用if时,此脚本似乎在AIX中正常工作。但是当我在linux中运行这个脚本时,它给出了一个错误can't locate Date/Calc pm in @INC。 当我在if循环中将其更改为require Date::Calc时,它在AIX服务器上给出了错误can't locate Date::Calc pm in @INC。对于Linux操作系统,else循环也是如此。

我如何实现共识?出于某种原因,我无法在一台服务器或另一台服务器上安装这些模块。

2 个答案:

答案 0 :(得分:4)

执行脚本是多次通过。 “使用模块”语句在与BEGIN块相同的阶段执行,而“正常”代码稍后执行。这意味着,您无法将if语句简单地包装在if-block中。你能做的是以下几点:

BEGIN {
   if ( $^O =~ m/aix/i ) { 
      require Date::Calc;
      *day_diff = sub { ... use Date::Calc::Delta_Days... }
   } else {
      require DateTime;
      *day_diff = sub { ... use DateTime here ... }
   }
}

day_diff( ... ); # will call either the DateTime or Delta_Days variant with a common interface

这样就可以在BEGIN块中定义一个函数。在这种情况下,实现取决于平台(更好地使用$^O而不是uname),但您也可以简单地检查模块是否可用,从而使代码更灵活:

BEGIN {
    if ( eval { require Date::Calc } ) {
        *day_diff = sub { ... use Date::Calc::Delta_Days... }
    } elsif ( eval { require DateTime }) {
        *day_diff = sub { ... use DateTime here ... }
    } else {
         die "cannot neither load Date::Calc not DateTime"
    }
}

答案 1 :(得分:4)

在Perl程序中,use语句总是在编译时发生。这意味着无论如何它们都会发生,即使它们位于不应执行的代码块中。所以你的use Date::Calc总是被执行,并且(因为它没有安装在你的非AIX盒子上)失败。

解决此问题的最简单方法可能是将每个use转换为require / import对。

if ( $OS=~/AIX/i ) {
  require Date::Calc;
  Date::Calc->import(qw(Delta_Days));
  ...;
} else {
  require DateTime;
  ...;
}

但是,为了避免将来进一步的痛苦,我肯定会调查在你的所有盒子上安装DateTime,以便你可以摆脱Date :: Calc。