http://www.perlmonks.org?node_id=927943

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

I don't know the easiest way to phrase this but I want to be able to have a script run continuiusly via the command line and when I want to add some input have it allow me to enter something while the script continues to run. I don't want it to pause and wait for me to type something in, maybe have it run until I do a key combo to let it know I want to enter something but I just don't want it to pause.

Is it possible to ask for STDIN without pausing?

Replies are listed 'Best First'.
Re: Ask for STDIN but don't pause for it
by kennethk (Abbot) on Sep 26, 2011 at 21:10 UTC
    You need to do what's called a non-blocking read. You will likely need to deal with some buffering issues on input/output, but Google can give you plenty now that you have a search term. In particular, see Non-blocking reading on STDIN?.
Re: Ask for STDIN but don't pause for it
by Kc12349 (Monk) on Sep 26, 2011 at 20:56 UTC

    You might take a look at a terminal module like Term::ReadKey to get started. I would run a loop, timer, or event architecture to periodically check for input and react accordingly.

    Should you want to go down the event route, AnyEvent bills itself as the DBI of event processing and is a good place to start.

Re: Ask for STDIN but don't pause for it
by zentara (Archbishop) on Sep 27, 2011 at 10:04 UTC
    There is alot of code around for doing this, here are a few methods to save you the search. They all involve running a loop of some kind. In the Glib examples, you can substitute another event loop of your choosing.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      I tried using the third example (IO::Select). However, this just ends up being an infinite loop printing the time. It never gets to reading STDIN.
        Works here. Are you hitting Enter to finish the line input? Otherwise use sysread.
        $ ./928062.pl
        Fri Sep 30 06:56:53 2011
        Fri Sep 30 06:56:58 2011
        asdfasfsad
        GLOB(0x7afe00)
        got: asdfasfsad
        Fri Sep 30 06:57:02 2011
        ^C
        

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
      i have tested this code, and it works, what i would like to see is a way of exiting from the loop without having to use ^C
Re: Ask for STDIN but don't pause for it
by ww (Archbishop) on Sep 27, 2011 at 21:13 UTC

    A very strong + + for zentara's third example (in the readmore, above).

    Alternately, however, your description makes me wonder (or maybe it's the mosquitos and the heat) if you really mean your process (script) has to "run continuously" -- the "maybe..." clause might be satisfied by something intermittently self-interupting. *

    Downside: user has to manually tell a process to resume (run again, in this trivial example); upside, -- I think -- might be slightly reduced overhead:

    #!/usr/bin/perl use strict; use warnings; use 5.012; # 927943 # process to run "continuously" from command prompt unless and until +I want to enter something... say "\n\t Enter 'i' or 'I' followed by <CR> or <CR> (only) to interupt +;\n\t any other char to continue"; my $NOP = "NoInterupt"; my $i = 1; sub continuous { my $continuous = 1; LABEL: $continuous += $i; $i++; say $continuous; # sleep 1; if ($continuous >= 25 ) { say "continuous >= 25, several iterations completed"; return; } goto LABEL unless ( $NOP ne "NoInterupt") ; } sub T { say "this is from sub T (which ain't doing much, but could be used + to deal with an operator input..."; say "for example, try 'R' next time"; return; } sub R { say "About to \"R\" ('run some code')... "; my @foo = qw/foo bar undef 123/; for my $foo(@foo) { say "\t $foo"; } return; } # MAIN START: continuous(); chomp ( my $interupt = <> ); if ( $interupt =~ /[A-H]|[J-Q]|S|[U-Z]/i ) { $NOP = "NoInterupt"; goto START; } elsif ( $interupt =~/r/i ) { R(); $NOP = "R"; goto START; } elsif ( $interupt =~/t/i ) { T(); $NOP="T"; goto START; } elsif ( ($interupt =~/i/i) || ($interupt =~ /''/)) { # exact +ly 'i' or 'I' or no entry $NOP = "\tSCRAM the reactor!"; say "$NOP, \$i: $i"; } =head execution and output: C:\>927943.pl Enter 'i' or 'I' followed by <CR> or <CR> (only) to interupt; any other char to continue 2 4 7 11 16 22 29 continuous >= 25, several iterations completed l 9 18 28 continuous >= 25, several iterations completed r About to "R" ('run some code')... foo bar undef 123 12 s 13 26 continuous >= 25, several iterations completed t this is from sub T (which ain't doing much, but could be used to deal +with an operator input... for example, try 'R' next time 15 u 16 32 continuous >= 25, several iterations completed i SCRAM the reactor!, $i: 17 C:\> =cut

    As my very tentative first para indicates, this may be utterly irrelevant, but it seemed worth a shot.

    Didactic distinctions -- ignore at will:

    wordnetweb.princeton.edu/perl/webwn
    (continuous) of a function or curve; extending without break or irregularity

    en.wiktionary.org/wiki/continuously
    (continuous) Without break, cessation, or interruption; without intervening time; Without intervening space; continued; protracted; extended; Not deviating or varying from uniformity; not interrupted; not joined or articulated;

    en.wiktionary.org/wiki/continuous
    (Continuous) Uninterrupted; unbroken

    ---------------

    Definition for continually:
    seemingly without interruption; "complained continually that there wasn't enough money".
    wordnetweb.princeton.edu/perl/webwn

    definition of continually by the Free Online Dictionary ...
    1. Recurring regularly or frequently: the continual need to pay the mortgage.
    2. Not interrupted; steady: continual noise; a continual ...

    Continual - Definition from the Free Merriam-Webster ...
    1. continuing indefinitely in time without interruption <continual fear>.
    2. : recurring in steady usually rapid succession ...

    The difference is small, but non-trivial (sometimes). :-)