2

I have a Perl script that has to wrap a PHP script that produces a lot of output, and takes about half an hour to run.

At moment I'm shelling out with:

print `$command`;

This works in the sense that the PHP script is called, and it does it's job, but, there is no output rendered by Perl until the PHP script finishes half an hour later.

Is there a way I could shell out so that the output from PHP is printed by perl as soon as it receives it?

3 Answers 3

8

The problem is that Perl's not going to finish reading until the PHP script terminates, and only when it finishes reading will it write. The backticks operator blocks until the child process exits, and there's no magic to make a read/write loop implicitly.

So you need to write one. Try a piped open:

open my $fh, '-|', $command or die 'Unable to open';
while (<$fh>) {
    print;
}
close $fh;

This should then read each line as the PHP script writes it, and immediately output it. If the PHP script doesn't output in convenient lines and you want to do it with individual characters, you'll need to look into using read to get data from the file handle, and disable output buffering ($| = 1) on stdout for writing it.

See also http://perldoc.perl.org/perlipc.html#Using-open()-for-IPC

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

Comments

2

Are you really doing print `$command`?

If you are only running a command and not capturing any of its output, simply use system $command. It will write to stdout directly without passing through Perl.

1 Comment

Yes, I am indeed doing exactly what I said I was doing in my question And yes, it is a sensible thing to do in this instance. Thanks for this solution - wonderfully simple and it works perfectly!
0

You might want to investigate Capture::Tiny. IIRC something like this should work:

use strict;
use warnings;

use Capture::Tiny qw/tee/;

my ($stdout, $stderr, @result) = tee { system $command };

Actually, just using system might be good enough, YMMV.

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.