How do I expand variables in Perl readpipe handler

2019-04-09 06:53发布

问题:

It seems that variables in backticks are not expanded when passed onto the readpipe function. If I override the readpipe function, how do I expand variables?

BEGIN {
*CORE::GLOBAL::readpipe = sub {print "Run:@_\n"};
}

`ls /root`;
my $dir = "/var";
`ls $dir`;

Running this gives:

Run:ls /root
Run:ls $dir

I am trying to mock external calls for a test code that I am writing. If there is a CPAN module somewhere which can help in taking care of all this, that would help too.

Update:

I have decided to use a really ugly workaround to my problem. It turns out that using readpipe() instead of backticks expands variables correctly. I am using an automatic script cleaner before running my tests which converts all backticks to readpipe() before running the tests.

e.g Running:

$ cat t.pl

BEGIN {
    *CORE::GLOBAL::readpipe = sub {print "Run:@_\n"};
}

`ls /root`;
my $dir = "/var";
`ls $dir`;
readpipe("ls $dir");

Gives:

$ perl t.pl
Run:ls /root
Run:ls $dir
Run:ls /var

I am still looking out for a cleaner solution though.

回答1:

That appears to be a bug in Perl. Use perlbug to report it.



回答2:

You probably want to use IPC::Run instead.

use IPC::Run 'run';

run [ "ls", $dir ], ">", \my $stdout or die "Cannot run - $!";

Or if you didn't want to capture the output, system() may be better

system( "ls", $dir ) == 0 or die "Cannot system - $!";