Eradicatore has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to write a quick perl/tk gui wrapper on a program that sometimes prompts the user for input. The program displays its status in text, and if I use Open3() and use a while loop like this on the STD_OUT stream:
while ($line = <OUT_STREAM>) { if ($line eq "something") { #do something here } }
things work pretty much until the program tries to get the user to type 'y' or 'n' for example if it needs to ask if it can overwrite a file of the same name. In this case, the carriage return doesn't happen, so the while loop is stuck. I thought about setting $| to zero, but that didn't seem to help. Do I have to go down to a loop that works char by char?

Basically this is something like a poor man's Expect, but since I'm working on windows, and I can't get perl Expect module working on windows, I want to use Open3. Any suggestions? Thanks!

Justin Eltoft

"If at all god's gaze upon us falls, its with a mischievous grin, look at him" -- Dave Matthews

Title edit by tye as single-word titles complicate future simple searches

Replies are listed 'Best First'.
Re: Open3
by BrowserUk (Patriarch) on Nov 20, 2002 at 20:01 UTC

    If there is any chance the the program you are wrapping is bypassing stdio (assuming its written in C) and reading the input buffer direct, then you will probably find it impossible to supply input to it from perl.

    A quick way to test if it is reading the input from STDIN, or bypassing that and accessing the keyboard buffer directly is to try supplying the answers to the prompts from a file via redirection.

    That is to say, run the program (not your script) from the command line and take it through a sequence that will exercise the prompts you wish to feed from your script.

    Then create a simple text file containing the answers to the prompts. Eg. If I use the command "rd /s subdir", I will be prompted with "C:\subdir, Are you sure (Y/N)?" so I create a file called y.txt that contains a single line with the char 'Y' followed by CRLF.

    I then invoke the command like this

    rd /s subdir <y.txt

    and the command accepts the 'Y' from the file and completes the command without interaction.

    However, some other programs will not except input supplied from a file this way as they do not read from STDIN. If the program you are trying to wrap is one of these, you have a problem.

    It may be possible to 'poke' characters directly into the keyboard buffer from Perl, but I have no idea how you would go about this.


    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

      That would be the Win32 API function SendInput. Call it using the Win32API:: module.
Re: Open3
by fglock (Vicar) on Nov 20, 2002 at 19:57 UTC

    You could output a "y\n" to the program using the open3 "writer" handle. This only works if the program expects input from STDIN.

      Thanks! I guess I should have been a little more specific. I want to be able to deal with a few cases like this, and update the GUI based on the different few possible cases like this. Is there a way to do something like what I'm doing above, where I deal with each line from the program, if the program doesn't end every single line with a carriage return like in this case?

      I guess I wasn't all the worried about being able to get a yes or no answer to the program. I was more worried about processing these lines that don't end in carriage return. My loop then turns infinite...

      Justin Eltoft

        I think that you will need to resort to reading char by char to achieve your aims. There is a little information regarding this in the documentation for perlfunc:getc which in turn refers you to the module Term::Readkey. This ought to work under Win NT/2K/XP as MS claim posix complience for the CLI's on these systems. If your on an earlier Win then you have less chance.

        Good luck.


        Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
        Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
        Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
        Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.