How do I pass Shell parameters to Perl script?

时光怂恿深爱的人放手 提交于 2021-01-28 19:07:21

问题


I am trying to find dates with in a certain format, I have done it before with perl(strftime), but that time I mentioned a static time, this time i need a variable $CURRENT_DAY here.

Below is the issue, when equate the CURRENT_DAY by using DAYHOUR=86400 and an integer, the variable is giving the right time, but once I put $CURRENT_DAY variable in the statement, the date would not decrease.

$ 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

回答1:


Your principal problem is that $CURRENT_DAY is a Perl script variable. By enclosing your Perl script in single quotes, there is no visibility to the shell's variable of the same name. Had you enabled warnings (e.g. with -w) you would have seen this.

There are a couple of ways to circumvent your problem. One is to use double quotes to encapsulate your Perl thus allowing the shell to first expand its variable's value before the Perl is run:

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

Another is:

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

Be advised that adding or subtracting 24-hours from a time to calculate yesterday or tomorrow will not correctly account for daylight saving changes. See this faq




回答2:


You may pass them as arguments in @ARGV:

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

$ DD=$(dd_seconds_ago 86400)

Without an argument and in the above context, shift shifts @ARGV, which is handy for shell one-liners like this




回答3:


Like Perl, sh doesn't interpolate in single quoted strings, so Perl sees $CURRENT_DAY instead of the actual number, and you've never assigned anything to that Perl variable. You could switch to a double-quoted string.

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

That's fine since $CURRENT_DAY is a number, but if you wanted to pass an arbitrary string, you'd use an env var or an argument.

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

or

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

Note that your code is buggy, though. There are two hours every year for which your code will give the wrong answer because not all days have 86400 seconds. Some have 82800, and others have 90000. (And that's assuming leap seconds don't factor in.) A Perl solution that doesn't suffer from that problem follows:

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

Or you could use date.

date -d "$DAY days ago" +%d



回答4:


I am assuming you want to pass the number of days in the past in the shell variable DAY and that you want the answer in the shell variable DD

So if it is the 20th of the month and the DAY is 1, then DD should be set to 19

You could modify your Perl command as follows:

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

Alternatively, you could use the GNU date command that is widely available

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

Using date is probably better at dealing with leap days, etc



来源:https://stackoverflow.com/questions/13973285/how-do-i-pass-shell-parameters-to-perl-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!