getting user input with timeout 

Newsgroups: comp.unix.shell
Date: 1999/02/03

and it seems you could do this:

#!/bin/sh
while true
 do
   echo -n "[hit |ENTER| to stop startx loop]"
   stty -icanon min 0 time 50
   read key in
     if [ ! -e $key ];then
        startx
     else
        exit 0
     fi
   stty sane
 done

Jim Surles

Timed keyboard input 

Newsgroups: comp.unix.shell
Date: 1997/05/31

http://groups.google.com/groups?hl=en&safe=off&th=8a5975360c80c043,5&seekm=WOLKOWSB.97Jun1085100%40dec.cuug.ab.ca#p

>Is there an equivalent of 'read' that gives up after a specified wait
>for user input?

Yes indeed. To start off there is 'read -t' in ksh93. Or you can use somthing like this

#!/bin/sh
exec </dev/tty
old=`stty -g`
stty raw -echo min 0 time ${1:-10}
echo -n How old are you?
IFS='' read -r a
stty $old
echo I think you are $a

which will wait a number of tenths of a second to get the user input. Or you can use the 'timed-read' command which comes with 'expect'. or you can use

#!/bin/sh
exec 2>/dev/null
( sleep ${1:-10) ; kill $$ ; ) </dev/null &
exec line

if you have 'line' available (or try replacing it with 'head -1' or 'sed 1q', but these tend to eat up too much input). Use as var=`scriptname timeout`.

Icarus

Timed keyboard input 

The following is an example that I think does exactly what you want:

stty raw
stty min 0 time 40      #'40' is for 4 seconds timeout
stty -echo
echo "Enter somthing : \c"
read var
stty -raw
stty echo
echo ${var}

Brian Wolkowski

Timeout for interactive input 

Newsgroups: comp.unix.shell
Date: 1998/09/26
http://groups.google.com/groups?hl=en&safe=off&th=b447f98bb582494e,3&seekm=6ujb2j%24442%241%40supernews.com#p
:     Anyone know how to create a timeout when the shell script is waiting
: for interactive input ?

There was a thread on this a few weeks ago, you can get probably still get the posts off of www.dejanews.com. I can't remember them all, but mine was something like:

case `uname` in
 SunOS) ALRM=14;;
 *) ALRM=14;;
esac

alarm () {
  alrm_tmout="$1"; shift
  if [ "$alrm_tmout" -ne 0 ]; then
    trap "trap $ALRM; wait \$alrm_pid; unset alrm_pid; $*" $ALRM
    alrm_ppid=$$
    (sleep $alrm_tmout; kill -$ALRM $alrm_ppid) >&- 2>&- &
    alrm_pid=$!
  elif [ -n "$alrm_pid" ]; then
    trap $ALRM
    kill -15 $alrm_pid
    wait $alrm_pid
    unset alrm_pid
  fi
}

Then use it like so:

echo 'prompt \c'
alarm 5 "signal=2"
read ans
alarm 0
echo "the answer was '$ans'; signal='$signal'"

You may have to check the value of ALRM, some older systems have been known to change it.

I would look at the news postings from a few weeks ago to find an appropriate solution for you.

Arcege

eread 

Here is a enhanced "read" function suitable for specifing timeouts (option -t) as well as many other features, including prompts, default values, unbuffered mode, and no-echo mode.

Eread has been optimized to function best as an autoloaded function. In such a case, a symbolic link in your FPATH may be made to "read", in which case the function below will be used in lieu of the builtin, with no change of code.

You do not specify the shell, so I presume that you are able to use the "autoload" built in to ksh(1).

-Brian

file "eread" in FPATH:

#! /bin/echo error: only source
#*TAG:34872 5:Sep 25 1998:0644:eread:
# Author: Brian Hiles <bsh@iname.com>
# Copyright: (c) 1996-1998
# Description: enhanced read function
# Name: eread
# Sccs: @(#)eread.sh 1.5 1997/12 bsh@iname.com (Brian Hiles)
# Usage: eread [-ce] [-dp string] [-t digit] -- [read-option]... [varname]...
# Varmap: /_1/default/,/_2/inkey/,/_3/noecho/,/_4/ntharg/,/_5/ostty/,/_6/prmpt/,/_7/readopts/,/_8/ring/,/_9/tmout/
# Version: 1.05

#01
eread() # [-ce] [-dp string] [-t digit] -- [read-option]... [varname]...
{       OPTIND=1 deflt= inkey= noecho= ntharg= ostty= prmpt= readopts= ring= tmout=
        while getopts :Ccd:Eep:t: _inst
        do      case $_inst in
                c)      inkey=ON ;;
                +c|C)   inkey= ;;
                d)      deflt=$OPTARG ;;
                e)      noecho=ON
                        autoload echon ;;       # sh: need to source ./autoload!
                +e|E)   noecho= ;;
                p)      prmpt=$OPTARG
                        autoload echon ;;       # sh: need to source ./autoload!
                t)      tmout=$OPTARG ;;
                [:?])   echo >&2 'usage: eread [-ce] [-d default]' \
                        '[-p prompt] [-t timeout] [-u filedes] --' \
                        '[read-option]... [varname]...'
                        return 2 ;;
                esac
        done
        # do: shift `/bin/expr 0$OPTIND - 1`
        if test 0$OPTIND -gt 0$#
        then    set X && shift
        else    eval ntharg=\$$OPTIND
                shift $OPTIND
                set -- "$ntharg" "$@"
        fi
        for _inst
        do      case $_inst in
                -*)     readopts="$readopts $_inst" shift ;;
                *)      break ;;
                esac
        done
        eval ${prmpt:+'echon "$prmpt"'}
        test X$noecho = XON -o X$inkey = XON && ostty=`/bin/stty -g`
        eval ${noecho:+'/bin/stty -echo'}
        #XXX -ixon ??
        eval ${inkey:+'/bin/stty -icanon -noflsh isig eof \^A'}
        if test X$inkey = XON
        then    # stty timeout apparently works only with _buffered_ input
                eval ${tmout:+'/bin/stty time ${tmout}0 min 0'}
                eval "${1:-REPLY}=`/bin/dd count=1 bs=1 2>/dev/null`"
        else    # another technique is needed with unbuffered input
                # ksh: turn off job control mode: "set +o monitor"
                eval ${tmout:+'trap ring=ON 2
                (sleep $tmout; kill -2 $$) >/dev/null 2>&1 &'}
                read $readopts ${*:-REPLY}
                eval ${tmout:+'test X$ring = X && kill $!
                trap 2'}
        fi
        eval ${deflt:+": \${${1:-REPLY}:='$deflt'}"}
        eval ${ostty:+'/bin/stty $ostty'}
        return 0
}

#02 EMBEDDED MAN-PAGE FOR "src2man"
 : '
#++
NAME
        eread - enhanced read function

SYNOPSIS
        eread [-ce] [-dp string] [-t digit] -- [read-option]... [varname]...

DESCRIPTION
        Eread extends the "read" builtin in sh(1) and ksh(1) to provide
        a default (given a null input), a selectable time limit, canonical
        input (a newline is not waited for), suppression of terminal echo
        (handy for the entering of passwords), as well as other features.

        In both the shells, if IFS is null the read will not strip leading
        and following whitespace before assigning it to the variable, as it
        will do by default. In ksh(1) only, the value of IFS is used to
        perform word splitting upon the input.

        Many Unix users are not aware that a simple built-in editor comprising
        the commands ^R, ^U, ^V, and ^W are almost always available (even
        during reads) as a feature of the terminal driver, performing the
        interactive functions redisplay-line, erase-line, quote-next, and
        backspace-over-word, respectively. ^H is similarly available to do
        backspace-over-character, but this is frequently mapped to another
        key, usually DEL or Backspace. Command "stty -a" to determine these.

        In addition: an undocumented feature in ksh(1) is that history
        substitution is available even within a read if $HISTFILE is set and a
        built-in editor is enabled with "set -o vi" or "set -o emacs". Give
        the line-up, line-down, or search-pattern commands of those editors
        to scroll from command to command (or input to input).  The "-s"
        option to "print" and "read" is available to append to this history
        non-interactively.

        See the man pages for sh(1) and ksh(1) for more details.

        Eread has been developed and tested under SunOS 4.x, but should ;)
        be portable to other Unices and bourne compatible shells.

OPTIONS
        -c      - Read one character; do not wait for a newline.
        -d str  - Specify default value <str> if input is null.
        -e      - Input is not echoed to terminal.
        -p str  - Print a prompt <str>.
        -t num  - Timeout the read after <num> seconds.

RETURN CODE
        0 for successful read, 1 for unsuccessful read, and 2 for error
        in options parsing.

EXAMPLE
        Refer to script $SIDEROOT/demo/eread.demo.

ENVIRONMENT
        IFS

SEE ALSO
        echon(3L)

BUGS
        Note that it makes no sense to specify more than one variable when
        eread is given the -c and/or -d options.

        Typing the INT signal (typically ^C) before terminal line discipline
        is reset after a -c or -e option may leave the terminal in an
        undefined state.

        This function works better in ksh(1) than in sh(1), although it is
        only written using the syntax of the latter shell.

#--
'

file "echon" in FPATH:

#! /bin/echo error: only source
#*TAG:56509 2:Sep 25 1998:0644:echon:
# Author: Brian Hiles <bsh@iname.com>
# Copyright: (c) 1996-1998
# Description: portable version of echo when no terminating newline is desired
# Name: echon
# Sccs: @(#)echon.sh 1.2 1998/04 bsh@iname.com (Brian Hiles)
# Usage: echon [string]...
# Varmap: /_1/bsd_nonl/,/_2/sysv_nonl/
# Version: 1.02

#01
echon() # [string]...
{       _1= _2=
        # Warning: always set variable ECHON to null whenever changing PATH
        # Warning: never export variable ECHON!
        case ${ECHON:=`echo -n X`} in
        -n*)    # SysV echo emulation: /usr/5bin/echo
                _1= _2=\\c ;;
        X)      # BSD echo emulation: /usr/bin/echo
                _1=-n _2= ;;
        *)      ;;
        esac
        echo $_1 "$@"$_2
        return 0
}

#02 EMBEDDED MAN-PAGE FOR "src2man"
 : '
#++
NAME
        echon - echo when no terminating newline is desired

SYNOPSIS
        echon [string]...

DESCRIPTION
        One would think that because the echo is a builtin in modern shells
        would guarantee a consistent option syntax for printing with a
        terminating newline. Unfortunately, because System V Unix and BSD
        Unix have a version of /bin/echo that implement different option
        syntax to print with no terminating newlines, scripts that desire
        to do so have to be manually configured.

        SunOS Unix has an echo builtin that will emulate either behavior
        depending on whether /usr/5bin appears before /usr/bin in the PATH.
        Unfortunately again, this is but a half-measure, and endemic only
        to that OS. Ksh "print" has a consistent interface, but scripts
        designed to be portable need to be scripted in sh(1).

        Echon serves to print with no newline in a completely portable fashion,
        regardless of the Unix implementation or whether echo is an external
        command or a builtin.

ENVIRONMENT
        ECHON   - caches result of test between System V echo and BSD echo.
        XXX

SEE ALSO
        eread(3L)

BUGS
        If echon has been previously executed and variable PATH is then
        changed, echon may erroneously use the wrong echo syntax. If PATH
        is changed, unset variable ECHON at the same time.
#--
'

Prompt user and use default response after a timeout 

Newsgroups: comp.unix.shell
Date: 2001-05-11 18:18:01 PST
http://groups.google.com/groups?hl=en&safe=off&th=dbad114c4f5a489e,5&seekm=3AFBDAFE.A7989309%40semax.fr#p

a portable and simple way would be :

tmout=5
trap : 15
(sleep $tmout; kill $$ &)
read x
trap - 15
echo $x

Cyrille

time limit for command before execution,while executing? 

Newsgroups: comp.unix.shell
Date: 2000/11/26
>How can I make it so the command only runs for a specified amount
>of time, say 5 seconds, then continues with the script?
my_command &
sleep 5; kill $!

time limit for command before execution,while executing? 

> > Useful - how would you make it continue if my_command exited before
> > the sleep had finished?
> Put at 'if' statement around the kill as such:
>     my_command &
>     sleep 5
>     PC=`ps -ef | grep $! | grep -v grep | wc -l `
>     if (( PC > 0 ))
>     then
>         kill $!
>     fi

That's a lot of forks just to see if "kill $!" would work. How about:

my_command &
sleep 5
kill -0 $! && kill $!

Regards,

Craig

How to set a "timeout" for commands 

http://www.oase-shareware.org/shell/scripts/quickies/timeout

Sometimes it is desirable to set a "timeout" for a command. If it does not complete within a certain period of time, it should be terminated automatically, and the script should continue.

The following example shows how to terminate a program ("ping 127.0.0.1") automatically if it does not finish execution within five seconds:

timeout=5                       # in seconds
ping 127.0.0.1 & cmdpid=$!      # Command to terminate
# Start "watchdog" process to terminate the command
# after $timeout seconds:
(sleep $timeout; kill -9 $cmdpid) &
watchdogpid=$!
wait $cmdpid                    # wait for command
kill $watchdogpid >/dev/null 2>&1

The example script starts a "timed" command in the background ("ping 127.0.0.1"), and then starts another background process (the "watchdog") that will terminate the command in 5 seconds.

It then waits for the "ping" command to terminate. If it terminates in time, the "watchdog" is terminated immediately, and the script continues.

If the command does not terminate in time, the "watchdog" process will "kill" it after the timeout period, and the script will continue. The subsequent termination of the "watchdog" will not be necessary (but will do no harm, either).

A more generic "timeout" script to monitor any arbitrary programs is available at the SHELLdorado "Scripts" section: