2012-12-20 121 views
1

我想用某种格式查找日期,我之前用perl做过(strftime),但那次我提到了一个静态时间,这次我需要一个变量$ CURRENT_DAY在这里。如何将Shell参数传递给Perl脚本?

下面是问题,通过DAYHOUR=86400和一个整数,该变量给出正确的时间等同的CURRENT_DAY的时候,但一旦我把$CURRENT_DAY变量在声明中,该日期将不会减少。

$ DAYHOUR=86400 
$ DAY=1 
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))` 
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'` 
$ echo $DD 
20 
$ DAY=`echo $(($DAY+1))` 
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))` 
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'` 
$ echo $DD 
20 
$ DAY=`echo $(($DAY+1))` 
$ echo $DAY 
3 
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))` 
$ echo $CURRENT_DAY 
259200 
$ echo `perl -e 'use POSIX; print strftime "%d", localtime time - 259200;'` 
17 
+0

是否有一个Perl脚本接受shell脚本参数的问题? – Lordlebu

+0

正如@ikegami在下面的评论中指出的那样,并非所有时间在所有时间的所有日子都有86400秒的时间。谨防夏令时间等。 – pilcrow

回答

4

您的主要问题是$CURRENT_DAY是一个Perl脚本变量。通过将您的Perl脚本封装在单引号中,不会看到相同名称的shell变量。如果您启用了警告(例如使用-w),您会看到这一点。

有几种方法可以规避您的问题。一种是使用双引号来封装你的Perl从而使外壳先扩展其变量的值Perl的运行前:

CURRENT_DAY=3 
perl -MPOSIX -wle "print strftime qq(%d),localtime time-(86400*$CURRENT_DAY);print $CURRENT_DAY" 
17 

另一个原因是:

export CURRENT_DAY=3 
perl -MPOSIX -wle 'print strftime qq(%d),localtime time-(86400*$ENV{CURRENT_DAY})' 

注意,加上或减去24从昨天或明天计算的时间将不会正确考虑夏令时的变化。见this faq

+0

在世界上大多数地方,每年有两个小时,这给了错误的答案。 – ikegami

0

我假设你想传递的天数在过去的shell变量DAY并要在shell变量DD

所以答案如果是本月20日和该DAY为1,那么DD应设置为19

你可以修改你的Perl命令如下:

DD=`perl -e 'use POSIX; print strftime "%d", localtime(time - ($ENV{DAY}* 86400))'; 

或者,你可以使用GNU date命令是广泛使用

DD=`date -d "$DAY days ago" +%d` 

使用date可能是在处理飞跃天好,等

+0

请注意,第一个片段需要'export DAY'工作。 – ikegami

3

您可以将它们作为论据@ARGV:

$ dd_seconds_ago() { perl -MPOSIX -e 'print strftime q(%d), localtime(time - shift)' "[email protected]"; } 

$ DD=$(dd_seconds_ago 86400) 

没有参数,并在在上面的情况下,shift移位@ARGV,这对于像这样的外壳单线很方便

+1

在世界上的大多数地方,每年有两个小时,这给了错误的答案。 – ikegami

+0

@ikegami,是。然后还有那些噩梦般的闰秒。 – pilcrow

1

像Perl一样,sh不会插入单引号字符串,因此Perl会看到$CURRENT_DAY而不是实际的数字,并且您从未将任何内容分配给该Perl变量。您可以切换到双引号字符串。

perl -MPOSIX -e"print strftime '%d', localtime time-$CURRENT_DAY;" 

这是自$CURRENT_DAY罚款是多少,但如果你想传递的任意字符串,你使用的环境变量或参数。

export CURRENT_DAY 
perl -MPOSIX -e'print strftime "%d", localtime time-$ENV{CURRENT_DAY};' 

perl -MPOSIX -e'print strftime "%d", localtime time-$ARGV[0];' -- "$CURRENT_DAY" 

请注意,你的代码是越野车,虽然。每年有两个小时你的代码会给出错误的答案,因为不是所有的日子都有86400秒。一些有82800,和其他人有90000(这是假设闰秒不计算在内。)一个Perl的解决方案,不从这个问题遭受如下:

perl -MDateTime -e'print 
    DateTime->today(time_zone=>"local") 
    ->subtract(days=>$ARGV[0]) 
    ->strftime("%d")' -- "$DAY" 

或者你可以使用date

date -d "$DAY days ago" +%d 
相关问题