damseldeebi
damseldeebi

Reputation: 137

Output stdin, stdout to file and console using Perl

I am trying a simple questionnaire using perl. I want to record the responses in a log file as and when a user inputs it. I'm having problem in redirecting the stdin to file.

Below is the code I implemented. Refer this.

open my $tee, "|-", "tee some_file.out";
print $tee "DO you want to continue?(y/n)\n";
$var=<STDIN>;
$var =~ s/[\n\r\f\t]//g;
if($var eq "y"){
    print $tee "Enter\n";
}
close $tee;

The output I'm getting now is, only after user input is provided the question is printed.

#in console
y
DO you want to continue?(y/n)
Enter

#some_file.out
DO you want to continue?(y/n)
Enter

Below is the expected output:

#in console
DO you want to continue?(y/n)
y
Enter

#some_file.out
DO you want to continue?(y/n)
y
Enter

I also found Duplicate stdin to stdout but really couldn't achieve what I want to. Am I missing something?!

Is there any cleaner solution available?

Upvotes: 0

Views: 405

Answers (1)

user2404501
user2404501

Reputation:

First of all, never use the phrase "redirecting the stdin to..." because stdin is input. It doesn't go to anything. It comes from somewhere.

It seems that what you expected is to have a copy of $var appear in your log file. Since you never printed $var to $tee there's no way that could happen.

So why did you think $var would appear in the log file? From the way you have shown us a copy of the log file next to a copy of what you see on the terminal, I guess that your reasoning went something like this:

  1. The tee put all of the output into the log file
  2. The tee also put all of the output on the terminal
  3. My program didn't output anything else besides what went into the tee
  4. The screen contents should match the log file

But there's a hidden assumption that's required to reach the conclusion:

3a. Nothing else was written to the terminal besides my program's output

And that's the part which is incorrect. When you type y into the terminal while your program is running, the terminal itself echoes what you type. It prints a copy in the terminal window, and also sends the character to your program's stdin. The y that you see on screen is not part of your program's output at all.

Since the echoing is done by the terminal and not by your program, you can't instruct it to also send a copy to your log file. You need to explicitly print it there if you want it to be logged.

You can ask the terminal to stop echoing, and then you take responsibility for printing the characters as they are typed so the user can see what they're typing. If you want to try that, see the Term::ReadKey module.

Or if what you really want is a complete record of everything that appeared on the terminal during the run of your program, maybe you should run it in the standard unix tool script, which is made for exactly that purpose.

(Side note: Did you know about the IO::Tee module? you can have teed output without an external process)

Upvotes: 2

Related Questions