Prev: FAQ 8.10 How do I read and write the serial port?
Next: FAQ 4.71 How do I handle binary data correctly?
From: Dilbert on 12 Jan 2010 09:35 I have the following program: use strict; use warnings; # redirect STDOUT to a file, but keep output to # screen alive (via the "tee" command) open STDOUT, "| tee logfile.txt" or die "Error: $!"; print "abc", "z" x 30, "enter a number >"; my $num = <STDIN>; print "\nYou entered: $num\n"; When I run this program, I see abczzzzzzzzzzzzzzzzzz but I can see no prompt "enter a number >" the cursor waits after the "...zzzz" I can blindly type in a number (e.g. 123), when I do this, I see the following on my screen: abczzzzzzzzzzzzzzzzzz123 zzzzzzzzzzzzenter a number > You entered: 123 The problem here is that STDIN and STDOUT are not synchronized anymore (probably due to the previous open STDOUT, "| tee logfile.txt"). -- and by synchronized I mean that the STDOUT buffer is flushed before every read from STDIN. How can I teach perl that STDOUT buffer is to be flushed before every read from STDIN, even after an open STDOUT, "| tee logfile.txt". I am on Ubuntu Linux: This is perl, v5.10.1 built for i686-linux-thread-multi (with 2 registered patches, see perl -V for more detail) Copyright 1987-2009, Larry Wall Binary build 1006 [291086] provided by ActiveState http://www.ActiveState.com Built Aug 24 2009 13:45:03
From: J�rgen Exner on 12 Jan 2010 11:15 Dilbert <dilbert1999(a)gmail.com> wrote: >How can I teach perl that STDOUT buffer is to be flushed before every >read from STDIN, even after an open STDOUT, "| tee logfile.txt". What happened when you asked the FAQ? perldoc -q flush perldoc -q buffer Of course this only tells perl to not buffer the output, your OS might still do its own buffering. jue
From: Dilbert on 12 Jan 2010 15:30 On 12 jan, 17:15, Jürgen Exner <jurge...(a)hotmail.com> wrote: > Dilbert <dilbert1...(a)gmail.com> wrote: > >How can I teach perl that STDOUT buffer is to be flushed before every > >read from STDIN, even after an open STDOUT, "| tee logfile.txt". > > What happened when you asked the FAQ? > > perldoc -q flush > perldoc -q buffer > > Of course this only tells perl to not buffer the output, your OS might > still do its own buffering. The FAQ gave me an example with setting autoflush(1), ... use IO::Handle; open my( $io_fh ), ">", "output.txt"; $io_fh->autoflush(1); .... but this disables buffering for the whole program, which is not what I want, I just want to flush automatically before every read from STDIN. The other example from the FAQ is better... $io_fh->flush; ....but still not satisfactory. In fact I would have to intervene in the programs and add an STDOUT->flush before each read from STDIN. It's a good solution, but I want something better. From what I understand, Perl puts STDIN and STDOUT in a "special relationship", such that STDOUT buffered under normal circumstances, but is *automatically* flushed before each read from STDIN, no need to manually flush using STDOUT->flush. The reason for that is that STDIN and STDOUT are both connected to the same terminal. Now, if I re-open STDOUT '| tee logfile.txt', Perl sees that STDOUT is not connected anymore to the terminal and therefore it cancels the "special relationship" between STDIN and STDOUT, the re-opened STDOUT is *not* flushed automatically before each read from STDIN. The point I make is that, yes, I re-open STDOUT to write to a flat file, but I use a backdoor and re-connect it via the "tee" command back to the terminal. What I want in this case (where STDOUT is re-opened to a flat file and then re-connected back to the terminal) is to establish the original relationship between STDIN and STDOUT where STDOUT is *automatically* flushed before each read from STDIN, no need to manually flush using STDOUT->flush.
From: Jim Gibson on 12 Jan 2010 17:48 In article <7d8990a2-0f33-4f0c-8a5e-b93e1cfab286(a)m3g2000yqf.googlegroups.com>, Dilbert <dilbert1999(a)gmail.com> wrote: > On 12 jan, 17:15, J�rgen Exner <jurge...(a)hotmail.com> wrote: > > Dilbert <dilbert1...(a)gmail.com> wrote: > > >How can I teach perl that STDOUT buffer is to be flushed before every > > >read from STDIN, even after an open STDOUT, "| tee logfile.txt". > > > > What happened when you asked the FAQ? > > > > � � � � perldoc -q flush > > � � � � perldoc -q buffer > > > > Of course this only tells perl to not buffer the output, your OS might > > still do its own buffering. > [problem with flushing output to screen before reading input snipped] It is likely that it is the tee program that is doing the buffering and needs to be flushed before input is read. Since this is not possible, you should consider some alternative approach that does not use an external program to duplicate output to the screen and a file. How about writing a function that takes input and writes it to the screen and a file? This has been done before, so search at http://search.cpan.org for "tee" and find modules such as File::Tee, IO::Tee, and PerlIO::tee. I have not used any of these, so I don't know if they will work for you. -- Jim Gibson
From: Peter J. Holzer on 12 Jan 2010 18:09 On 2010-01-12 22:48, Jim Gibson <jimsgibson(a)gmail.com> wrote: > [problem with flushing output to screen before reading input snipped] > > It is likely that it is the tee program that is doing the buffering and > needs to be flushed before input is read. No. tee doesn't buffer (at least not the implementations I'm familiar with). Dilbert correctly (except that he erroneously calls a pipe a "flat file", but that makes no difference in this context) the behaviour required for stdio by the C standard. Apparently perlio emulates this behaviour. hp
|
Next
|
Last
Pages: 1 2 3 Prev: FAQ 8.10 How do I read and write the serial port? Next: FAQ 4.71 How do I handle binary data correctly? |