2012-12-20 209 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 
相關問題