it works fine for non-interactive commands, however input prompts are not displayed until after input has been received. The result is that the user cannot see the prompt and does not know what they are being prompted for, or even that they are being prompted.
Maybe I'm misunderstanding something here but...of course the user doesn't see the prompts, how could they?
The program $cmd in your example will write it's prompts to stdout, and $pipe->reader( $cmd ) runs that command, redirecting it's stdout to a pipe, so that your program can read it.
Just as you don't see the output from dir when you do dir >file, so you are not going to see the prompt from (say) pause when you do pause > junk because it ends up in the file.
C:\test>type junk
Press any key to continue . . .
Same thing with your pipe, any prompts from the command will end up going via the pipe into your program. Unless the command was printing to the console via some other filehandle (eg. stderr) or using direct console IO.
Here is a way that might work for you. If you don't have a copy of the tee utility, you can get a Win32 version as a part of UnxTools. You then issue your command as
$pipe->reader( 'yourprog arg arg | tee CON' );
Which will allow the user to see the prompts and respond to them
C:\test>perl -MIO::Pipe -we"$p=IO::Pipe->reader('(pause & dir z)|tee C
+ON');@i=<$p>;print qq[Got '$_']for @i"
Press any key to continue . . .
Volume in drive C has no label.
Volume Serial Number is BCCA-B4CC
Directory of C:\test
File Not Found
Got 'Press any key to continue . . .
'Got ' Volume in drive C has no label.
'Got ' Volume Serial Number is BCCA-B4CC
'Got '
'Got ' Directory of C:\test
'Got '
'
with the caveats that
- your program will also receive a copy of the prompts in it's input which you could probably filter out;
- The user will also see all the output from the command echo'd on the screen which may or may not be a problem.
What it comes down to is that there is no way for the pipe to know which output (to stdout) from the command is intended for interaction with the user, and what is a part of the final output you wish to capture. This is not a win32 limitation (of it's forking or anything else), you will get the same results on *nix also.
Finally, you may or may not know that IO::File->reader is effectively the same as doing
$pid=open CMD, "$cmd |";
@input = <CMD>;
eg. C:\test>perl -e"$pid=open CMD,q[(pause & dir z)|tee CON |];@i=<CMD>;pr
+int qq[Got '$_']for @i"
Press any key to continue . . .
Volume in drive C has no label.
Volume Serial Number is BCCA-B4CC
Directory of C:\test
File Not Found
Got 'Press any key to continue . . .
'Got ' Volume in drive C has no label.
'Got ' Volume Serial Number is BCCA-B4CC
'Got '
'Got ' Directory of C:\test
'Got '
'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|