I need to execute a command from my Perl script, which is going to take a while (1-2 hours). I want to be able to see the output of the command, so that my script can check everything went OK, but as it takes such a long time, I'd like the user to see the commands output while it runs, too.
What I've tried:
backticks
- Can only get output when command is finishedsystem
- Can only get output when command is finishedopen
- Almost perfect - but the commands output is buffered, meaning users don't see an update for a long time. Internet is full of suggestions to set$| = 1
but apparently this only affects input buffering and doesn't work- Piping to
tee
- Similar results toopen
- 'tee' only seems to print later - Re-directing output and Using
Proc::Background
andFile::Tail
- Almost perfect again, but can't think of an elegant way to stop the print loop
Would love to have a suggestion!
Edit: I've accepted Barmars answer. I believe it works because Expect.pm uses a pseudo-terminal. Just to others looking at this question in future, this is how I've implemented it:
my $process = Expect->spawn($command, @params) or die "Cannot spawn $command: $!\n";
while ($process->expect(undef))
{
print $process->before();
}