我正在尝试使用脚本来获取否。从现在到未来的日期之间的几天。我打算从一个公共位置在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
循环也是如此。
我如何实现共识?出于某种原因,我无法在一台服务器或另一台服务器上安装这些模块。
答案 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。