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

I'm working on a perl program that's an interactive-front end for launching a lot of long, slow processes I have to do. When one finishes, I would like the program to ask if I would like to continue. That isn't too hard.. but if I don't answer in X amount of time, I want it to stop waiting and to continue on its own. How do I do this?

I'm imagining something like:

X done. Y starting in 15 seconds. Press any key to do Z instead.
X done. Y starting in 14 seconds. Press any key to do Z instead.
...snip...
X done. Y starting in 1 second. Press any key to do Z instead.
No input received, doing Y.

... etc. I'm totally stumped as I have no idea how to do this with <STDIN>. How do I do this?

Replies are listed 'Best First'.
Re: CLI Interactivity - Timed Prompt
by kyle (Abbot) on Jan 25, 2008 at 17:18 UTC
      Awesome, thank you.
Re: CLI Interactivity - Timed Prompt
by locked_user sundialsvc4 (Abbot) on Jan 25, 2008 at 17:27 UTC

    What's happening here is that the alarm() function arranges for an “alarm signal” to be sent to the program after a certain interval. The arrival of this signal causes an exception to be raised, which is caught by the eval construct.

    The error-message for an alarm-timeout will contain the word “alarm,” and the error-checking code verifies that this is so. (Any other error is re-raised with die.)

    This is a pretty-typical method of handling timeouts because as you can see, any time-consuming process can be interrupted by a signal ... and a poll/select socket-based program can easily handle it as well.

    “alarms” are designed to be a fairly low-resolution timing mechanism.

    Note:   Don't forget to quash the alarm if you do get input from the user... otherwise the alarm will still come in “right on time,” probably with most-unfortunate consequences.

      > Note: Don't forget to quash the alarm if you do get input from the user... otherwise the alarm will still come in “right on time,” probably with most-unfortunate consequences.

      Haha.. Even though you warned me, man, this got me! I was witnessing crazy behavior and pulling my hair out, wondering what was going on until I remembered your comment. :)
      Thanks, it looks like the alarm will do what I need it to do. The low-resolution is fine. :)
Re: CLI Interactivity - Timed Prompt
by leighsharpe (Monk) on Jan 26, 2008 at 12:19 UTC
    Use Term::ReadKey.
    The ReadKey function allows yout to specify a timeout. example (untested):
    print "X done. Y starting in 15 seconds. Press any key to do Z instead +.\n"; my $selection=ReadKey(15); if ($selection) { # Key pressed. Do Z. } else { # No key pressed. Do Y. }
    Could easily be altered to use ReadKey(1) and print the prompt every second.
Re: CLI Interactivity - Timed Prompt
by warkruid (Novice) on Jan 26, 2008 at 19:50 UTC
    If your processes are purely commandline and/or terminal based programs then I suggest you also take a look at the Expect module in the CPAN archive.
    It is a perl "derivate" of the expect program by Don Libes.

    With Expect you can:
    - spawn processes
    - pass arguments to them
    - ask the user for input
    - search for certain output, and act on it
    - set timeouts on actions and responses

    The ability to check on any error messages that your processes may generate, makes for _FAR_ more robust scripts

    Expect::Simple is a wrapper around the Expect module that simplifies the syntax somewhat ;-)

    For further (heavy) reading:
    "Exploring Expect" Don Libes 1st ed. 1995 O'Reilly & Associates 566 p.