screen output lags behind, or script appears to 'switch statements'

  • Thread starter Florian von Savigny
  • Start date
F

Florian von Savigny

Hi,

I have a very weird problem: I wrote a fairly long script with plenty
of screen messages, and a few prompts for user input. Though the
script does what it is supposed to, a very bizarre error occurs:

At a certain screen message, the script seems to freeze ('ps -a' on
another terminal reveals that the process is sleeping). Only when you
hit the return key, it will continue, and it will regard the next
prompt as already answered (i.e. it seems to have taken the "Enter" as
a newline input from STDIN). In other words, you have to answer the
prompts "in advance", knowing they are due in a few lines.


Extracts from the code and the output may further clarify this:

print "about to invoke cdrecord: Unmounting $image_mountpoint ...";
$status = system("umount -d $image_mountpoint");
print " done.\n";
abort_wisely() if $status;
print "\aIf an empty CD-R of " . $cd_sizes[0] / 1048576 .
"MB (as you announced) is in $cdwriter, press Enter: ";
$go_on = <STDIN>;
$status = system("cdrecord $cdrecord_options $add_options $image");

This is supposed to produce the following screen output (never mind
the actual variable values):

about to invoke cdrecord: Unmounting /mnt/1/ ... done.
[bell]
If an empty CD-R of 650MB (as you announced) is in /dev/scd0, press Enter: _

(I've put an underscore where the cursor should appear). If you now
hit Enter, it should run cdrecord as specified in the system()
functions argument. Right?

But what it actually produces is the following:

about to invoke cdrecord: Unmounting /mnt/1/ ..._

(underscore = cursor) And here the script seems to have
frozen. 'mount' on another terminal reveals that /mnt/1 HAS been
unmounted, but " done.\n" does not appear. Until you hit "Enter":

done.
[bell]
If an empty CD-R of 650MB (as you announced) is in /dev/scd0, press Enter: <which is immediately followed by cdrecords screen messages>

IOW, after "..., press Enter: ", no keyboard input is waited for; the
program just goes on.

I think this is very bizarre behaviour. Although it appears as though
perl executes the

$go_on = <STDIN>;

statement BEFORE the

print " done.\n";

statement, I personally favour the hypothesis that screen output
somehow suffers a delay. I.e. I suspect the program HAS arrived at the
statement "$go_on = <STDIN>;", and it certainly HAS executed the
preceding statements and is now duly waiting for keyboard input, but
it is somehow on the way to the screen that those messages are held
back.

This seems to be substantiated by the fact that after this error, ALL
prompts are printed AFTER having been answered (even one which was
correct before that). And if I am on the right track, it needn't even
be the lines of code I have printed here who are to blame, it could be
anything else. It needn't even be the script - however, it has only
happened with this script so far.


Does anyone have a clue what kind of problem this could be, and where
it typically arises?


--


Florian v. Savigny

If you are going to reply in private, please be patient, as I only
check for mail something like once a week. - Si vous allez répondre
personellement, patientez s.v.p., car je ne lis les courriels
qu'environ une fois par semaine.
 
B

Brian McCauley

Florian von Savigny said:
I have a very weird problem:
print "\aIf an empty CD-R of " . $cd_sizes[0] / 1048576 .
"MB (as you announced) is in $cdwriter, press Enter: ";
$go_on = <STDIN>;
I personally favour the hypothesis that screen output
somehow suffers a delay. I.e. I suspect the program HAS arrived at the
statement "$go_on = <STDIN>;", and it certainly HAS executed the
preceding statements and is now duly waiting for keyboard input, but
it is somehow on the way to the screen that those messages are held
back.

You are so close to getting to your answer. You have figured out that
some sort of buffering is going on.

perldoc -q buffer

Pay particular note to "Serial devices (e.g. modems, terminals) are
normally line- buffered, and stdio sends the entire line when it gets
the newline."

Note also that a newline that's echoed while reading STDIN does not go
via STDOUT so does not count for this purpose.

You probably want to put STDOUT->flush() before reading from STDIN.
(flush is in IO::Handle).

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
A

AlV

Florian said:
Hi,
Hi,

[snip]

Does anyone have a clue what kind of problem this could be, and where
it typically arises?

You should suppress Perl buffering mechanism before printing a string
without newline character. For example, you might do this by setting $|
to something true (1 is a reasonable value for that purpose ;o)

Restoring $| to false might be a good idea thereafter.

Actually, $| has an "use English;" name: $OUTPUT_AUTOFLUSH
 
F

Florian von Savigny

Thanks a lot, I had really not figured out that it was 'no newline at
the end' what those print statements had in common. I did think
something real weird was going on, possibly something beyond the realm
of Perl (such as the shell commands I am calling).

I have taken to setting and resetting $| before and after each such
print statement, which may have been more work than Brian's proposal
after all. But in any case, it has worked like a snap.

Many thanks!

--


Florian v. Savigny

If you are going to reply in private, please be patient, as I only
check for mail something like once a week. - Si vous allez répondre
personellement, patientez s.v.p., car je ne lis les courriels
qu'environ une fois par semaine.
 
N

news

Florian von Savigny said:
I have taken to setting and resetting $| before and after each such
print statement, which may have been more work than Brian's proposal
after all. But in any case, it has worked like a snap.

You may find it's easier - and more readable - just to set $| at the
beginning of the script or section. The tradeoff is buffering (efficiency)
vs no buffering (it works as you expect).

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top