1

I'm trying to use GNU Date to get the seconds between two dates. The reason I'm using GNU Date is for performance (in testing was 10x faster than Perl) for this purpose. However, one of my arguments is a perl variable. Like this:

my $b_row="2012-01-05 20:20:22";
my $exec =qx'CUR_DATE=`echo $(date +"%F %T")` ; echo $(($(date -d  "$CUR_DATE" +%s)-$(date -d  "$b_row" +%s)))';

The problem is that b_row is not being expanded. I've tried a couple different solutions (IPC::System::Simple) being one, tried adjusting the backticks etc. No success, any ideas how to do this appropriately? The main thing is I need to capture the output from the bash command.

1
  • How were you doing the calculation in Perl that wound up 10x slower than starting 4 processes? I suspect that it can be done more efficiently. Commented Jan 6, 2012 at 2:14

3 Answers 3

1

Make it easier on yourself and do the minimum amount of work in the shell. This works for me:

my $b_row = '2012-01-05 20:20:22';

my $diff = qx(date -d "\$(date +'%F %T')" +%s) -
           qx(date -d            "$b_row" +%s);

Just be absolutely sure $b_row doesn't have any shell metacharacters in it.

Sign up to request clarification or add additional context in comments.

Comments

0

That's because you use ' :

           Using single-quote as a delimiter protects the command from
           Perl's double-quote interpolation, passing it on to the shell
           instead:

               $perl_info  = qx(ps $$);            # that's Perl's $$
               $shell_info = qx'ps $$';            # that's the new shell's $$

3 Comments

Arkadiy, thanks for your response. I tried that earlier, I get this error: sh: -c: line 0: syntax error near unexpected token (' sh: -c: line 0: CUR_DATE=echo 0 0date +"%F %T") ; echo 0 0(0 0date -d "" +%s)-0 0date -d "2012-01-05 20:20:22" +%s)))'
It seems to have a problem dealing with the (()) in the date calculation.
It probably interpreting %s as a hash. Use \% instead.
0

qx has the feature of letting you choose a convenient delimiter, including the option of whether to interpolate the string or not (by choosing ' as the delimiter). For this use case, sometimes you want interpolation and sometimes you don't, so qx (and backticks) may not be the right tool for the job.

readpipe is probably a better tool. Like the system EXPR command, it takes an arbitrary scalar as input, and you have all of Perl's tools at your disposal to construct that scalar. One way to do it is:

my $exec = readpipe 
    'CUR_DATE=`echo $(date +"%F %T")` ;'   # interp not desired
    . ' echo $(($(date -d  "$CUR_DATE" +%s)-$(date -d  "'
    . qq/"$b_row"/                         # now interp is desired
    . ' +%s)))';                           # interp not desired again

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.