3

I have two Perl scripts — let's call them script.pl and script2.pl.

script2.pl updates to the command line, as in:

print "Progress $progress percent...\r"; 

In order to get this to work I had to turn on autoflush at the start of script2.pl:

$|++; 

Now, the problem arises because I have to have script2.pl called from script.pl, and this — the updating/flushing — only seems to work when script2.pl is run directly, not when it's called from script.pl.

I've tried various ways of calling script2.pl, from system() to backticks and in no case does the updating happen.

Am I missing something about handling stdout output when one Perl script is called from another?

2
  • How do you call script2.pl from within script.pl? Commented Apr 30, 2018 at 15:59
  • Currently I'm just using `script2.pl` in backticks. Commented Apr 30, 2018 at 16:17

1 Answer 1

3

Calling with backticks will spawn a new perl process, and for that process, the auto-flushing will be set. That means that whatever output comes out of script2.pl will come out as soon as it gets printed. Of course doing

my $output = `perl script2.pl`; 

will mean you are not actually reading it while it's being output, but rather you're asking for all the output to end up in $output when it's done.

The $| in the perl process that runs script2.pl has no influence on script.pl. If you want your script.pl process to have unbuffered output, turn off buffering there.


An alternative might be to not run script2.pl as a separate process, but rather to refactor it to be a module and call it properly, or use do or require to call it once. In either case the change to $| would then happen within the same Perl interpreter, and thus would have an effect.

Of course it's not a good idea if an internal part of your application messes with your application's output buffering. The best way would be to refactor this to be a module without changing the buffering in that module, and in your program where you use it, set the buffering to what you need it to be for that specific program. Always let the consumer decide what they want, even if that's only yourself.

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

4 Comments

It might be that I misunderstood your question. In that case, please clarify.
No, I think you got me. I appreciate the clarification. I thought since I'd turned off buffering in both with $|++ and since they were being executed in the same console, I'd see it — but I guess it makes sense that they're not technically the same stdout. Thanks for this answer.
@KT_ if you've got it turned on in both scripts it should be working. However if you shell out from script.pl to script2.pl it really doesn't matter whether script2.pl has $|++ or not.
@KT_: Running a program using backticks stores the output instead of printing it to the screen. You can print the result after the run finishes, but you will get the whole thing at once.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.