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

Hello Monks!

I am building a script that sets up our servers from a basic install to the correct settings. I have to send this output to an IQ (installation qualification) file.

This works very well until I get to the point where I do an update from RedHat and the RedHat script requires user input whether or not to continue.

When run without the STDOUT tee the question shows up ok. However when STDOUT uses the tee it does not.

Here is my code:
open (STDOUT, "|tee /var/tmp/IQOQ.txt"); &y_up; ##run yum update sub y_up { my $y = "/usr/bin/yum"; my $u = "update"; system("$y", "$u");
And here is the output and where it stops with the above code
Transaction Summary ====================================================================== +========== Install 3 Package(s) Update 67 Package(s) Remove 0 Package(s)
Here is the output with the STDOUT code commented:
Transaction Summary ====================================================================== +============================== Install 3 Package(s) Update 67 Package(s) Remove 0 Package(s) Total download size: 114 M Is this ok [y/N]:
How can I set this up so that the required user input is available?
Thanks Monks!
Update!
Thanks to all of you that answered. Some notes to the answers: Yes I could use the -y flag but management wanted to keep that part flexible.
I thought about the STDERR but never got around to trying it.
@Marshall-that may have worked but again I didn't get around to trying it.
In the end what I did was this:
close STDOUT; #close the original STDOUT tee to file open (STDOUT, ">/dev/tty"); #open STDOUT back to just the terminal system("$y", "$u"); #my $rhup = `"$y" "$u"`; my $err = $?>> 8; open (STDOUT, "|tee -ai /var/tmp/IQOQ.txt"); #Now re-tee STDOUT since + we aren't done

I did it like this as yum prints it's out put to /var/log/yum.log and I can get the list of updates from there. All I need for the IQOQ is to know whether or not it successfully completed which I do capture.
Thank you everyone for your help!

Replies are listed 'Best First'.
Re: Getting user input with STDOUT tee to file
by moritz (Cardinal) on Oct 15, 2009 at 18:21 UTC
    It's likely buffering that's causes you pain - add $| = 1 to turn it off.

      I wish that would have worked but it didn't :(

      I also tried autoflush
      open (STDOUT, "|tee /var/tmp/IQOQ.txt"); STDOUT->autoflush(1); #$| = 1;
        Maybe the problem could be in the tee program? Just for grins, try running with my Perl version of tee. I doubt that it has a chance, but I've seen weirdo problems with tee before on Windows. Anyway here is my tee.pl and this tee is doing unbuffered output:
        #!usr/bin/perl -w use strict; $|=1; #turn autoflush on sub usage () { print "TEE USAGE:\n". " program | tee outfile\n". " sends stdout from program to outfile\n"; exit; } my $filename = shift @ARGV; usage unless $filename; open (OUTFILE, ">", "$filename") or (die "Can't open OUTFILE: $!"); while (<>) { print; print OUTFILE; }
        Not claiming anything, but just curious if this makes a difference.

        Update: I posted a simple program at Re^3: Trouble with an array inside a format call that demo's what the $|=1 does with just a few print statements. This is why I think that a simple test with my tee.pl is worth a couple of minutes of testing. tee is doing the printing and it won't matter if your app that sends input into tee is unbuffered or not if tee is doing some buffering.

Re: Getting user input with STDOUT tee to file
by Bloodnok (Vicar) on Oct 15, 2009 at 20:24 UTC
    I've noticed that occasionally, rather perversely, some programs use STDERR to perform user prompting ?!

    system captures neither STDOUT nor STDIN and the command you issue captures only STDOUT - does the problem lie therein ?

    A user level that continues to overstate my experience :-))
      I've seen that too! ie, using STDERR inappropriately to do user communication. But in this case, if that was happening (a print of the question to STDERR), the OP would have seen the question on the screen.

      I suspect that in the OP's situation, it could be that unbuffering the output into the STDOUT pipe is a necessary, but not sufficient condition. The tee program also has to use unbuffered output!

      I updated my previous post with a link to another thread where I posted a simple program that demonstrates what $|=1 does using only half a dozen print statements.

Re: Getting user input with STDOUT tee to file
by jakobi (Pilgrim) on Oct 15, 2009 at 20:54 UTC

    I call the STDERR suggestion, and raise with /dev/tty prompting and user input (remember zap the process zapper :) ?).

    Seriously: Consider using yum -y to auto-answer-yes instead of prompting, esp. as you want to automate the installation anyway. For the general case, there's also the 'yes' command to provide simple input to obnoxious semi-interactive programs. For worse cases, there's expect and the corresponding Perl modules. To capture all input/output, there's also script for capturing a session transcript (albeit complete with _all_ of escape code sequences and curses(sic!)).

    To dup STDERR onto STDOUT with 2>&1 and print it as part of Perl's STDOUT: print qx!yum ... 2>&1!. But I tend to dislike the implicit redirect of system (though it is honored e.g. on Linux).

    One final note: a program can test whether a file descriptor is a tty and modify its behaviour accordingly (check perldoc -f -t and the -t operator).

    cu
    Peter
Re: Getting user input with STDOUT tee to file
by gmargo (Hermit) on Oct 15, 2009 at 23:16 UTC

    Doesn't yum have a "-y" option? Avoid the question entirely.