# SccsId[] = "%W% (USL function) %G%"
              RKN_name="READKEY_NOECHO"
              if [ ".${SECONDS}" = "." ]; then # Bourne function already loaded?
                 [ ."`set|egrep '^$RKN_name\(\)\{$'`" != . ] && RKN_loaded=1
              else # Korn or Bash shell and function already loaded?
                 if [ `expr "\`uname -s\`" : "[Ll][Ii][Nn][Uu][Xx]"` -eq 0 ]; then
                    [ ."`typeset +f|awk '/^'$RKN_name'[=\(]?/'`" != . ] && RKN_loaded=1
                 else # Linux
                    [ ."`typeset -F|awk '/^'$RKN_name'[=\(]?/'`" != . ] && RKN_loaded=1
                 fi
              fi
              if [ 0${RKN_loaded} -eq 0 ]; then
              #----------------------------------------------------------------------#
              READKEY_NOECHO()
              #----------------------------------------------------------------------#
              {
                if [ .$TERM != . ]; then # If running interactively, prompt user.
                   #------------------------------------------------------------#
                   # If the following variables are not set, use these defaults.#
                   #------------------------------------------------------------#
                   : ${OZ:=`uname -s 2> /dev/null|tr '[A-Z]' '[a-z]' 2> /dev/null`}
                   : ${script_name:=`basename $0`}

                   RKN_ID="$script_name($RKN_name)"

                   RKN_oldstty=`/bin/stty -g`
                   RKN_stty_status=$?
                   if [ $RKN_stty_status -ne 0 ]; then
                      echo "$RKN_ID" \
                        "Problems saving original terminal settings." 1>&2
                      return $RKN_stty_status
                   fi

                   #---------------------------------------------------------------#
                   # Just in case the user ^C's out of this, we'll restore their   #
                   # stty settings before exiting.  (TRAP_EXIT is a shell library  #
                   # function that may or may not be set.  To ensure a gracious    #
                   # exit, we follow the trap call to it with the "exit 1".  This  #
                   # way, one way or the other, we exit cleanly.                   #
                   #---------------------------------------------------------------#
                   trap "/bin/stty $RKN_oldstty; TRAP_EXIT; exit 1" 1 2 3 9 15

                   if [ ."$OZ" = ."sunos" -o ."$OZ" = ."linux" ]; then
                      /bin/stty -icanon -isig -echo min 1 time 0
                   else
                      /bin/stty -icanon       -echo min 1 time 0
                   fi
                   RKN_stty_status=$?

                   if [ $RKN_stty_status -ne 0 ]; then
                      echo "$RKN_ID"                              \
                         "Problems setting stty to terminal mode" \
                         "and turning off echoing." 1>&2
                      return $RKN_stty_status
                   fi

                   /bin/dd bs=1 count=1 <&0 2> /dev/null
                   RKN_dd_status=$?

                   /bin/stty $RKN_oldstty
                   RKN_stty_status=$?
                   if [ $RKN_stty_status -ne 0 ]; then
                      echo "$RKN_ID" \
                         "Problems resetting original stty to '$RKN_oldstty'" 1>&2
                      return $RKN_stty_status
                   fi

                   #---------------------------------------------------#
                   # Restore traps to something a bit more civilized.  #
                   #---------------------------------------------------#
                   trap "TRAP_EXIT: exit 1" 1 2 3 9 15

                   if [ $RKN_dd_status -ne 0 ]; then
                      echo "$RKN_ID" \
                         "Problems with 'dd' command obtaining the character." 1>&2
                      return $RKN_dd_status
                   fi

                   echo "$RKN_string"|tr -d "\015"
                   return 0 # Ah, the sweet smell of success.
                else
                   return 1
                fi
              } # "RKN_" prefix identifies this function's variables
              fi

              #======================================================================#
              #                       D O C U M E N T A T I O N                      #
              #======================================================================#
              #                                                                      #
              #      Author: Bob Orlando                                             #
              #                                                                      #
              #        Date: March 17, 1997                                          #
              #                                                                      #
              #  Program ID: readkey_noecho.sh                                       #
              #                                                                      #
              #       Usage: READKEY_NOECHO <no arguments>                           #
              #     Example: key=`READKEY_NOECHO`                                    #
              #                                                                      #
              #     Purpose: Read an unechoed single key from the keyboard without   #
              #              having to press carriage return.                        #
              #                                                                      #
              #     Globals: No global variables are assigned in this function.      #
              #              "RKN_" prefix identifies local function variables.      #
              #                                                                      #
              # Exit_status: Returns success or non-zero for failure.                #
              #                                                                      #
              #       Calls: None.                                                   #
              #                                                                      #
              #       Notes: If running in batch mode (e.g. from cron), then the     #
              #              function simply returns a null and exit status of 1.    #
              #                                                                      #
              #     Origins: The code for this function based on Ed Schaefer's       #
              #              "Returning a Single Character in a UNIX Shell Script"   #
              #              (Sys Admin magazine, April, 1997, pp. 53-55).           #
              #                                                                      #
              #    Modified: 2004-03-03 Bob Orlando                                  #
              #                 v1.7  * Change set|egrep|awk to just set|egrep.      #
              #                                                                      #
              #----------------------------------------------------------------------#
            
Artificial Intelligence is no match for natural stupidity.
©Copyright Bob Orlando, 1997-2011
All rights reserved.
http://www.OrlandoKuntao.com
E-mail: Bob@OrlandoKuntao.com
Last update: Jan. 26, 2011
by Bob Orlando