Dangeruss
Dangeruss

Reputation: 73

Perl String Interpolation in Bash Command

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.

Upvotes: 1

Views: 639

Answers (3)

mob
mob

Reputation: 118605

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

Upvotes: 0

Sean
Sean

Reputation: 29772

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.

Upvotes: 1

user3458
user3458

Reputation:

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 $$

Upvotes: 0

Related Questions