Linux bash - retype user input

I have an old script shell that needs to be moved to bash. This script prints the progress of some actions and waits for user commands. If the user does not take any action within 15 seconds, he redraws with a new progress, and the timer starts again. Here is my problem:

I'm trying to use read -t 15 myVar- this way, after 15 seconds, the wait loop will restart. However, there is a script that causes me a problem:

  • the screen is redrawn and the script is waiting for input (displays Enter command:')
  • user enters foobut does not clickenter
  • after 15 seconds, the screen is redrawn again, and the script is waiting for input - note that it foodoes not appear anywhere on the screen (prints " Enter command:")
  • user enters barand clicksenter

At this point, the variable $myVarcontains. ' foobar'

What I need? I am looking for a way to find the first line typed by the user, so I was able to re-display it after updating the status. Thus, the user will see: Enter command: foo

In Solaris, I could use stty -pendinto save the input in some kind of buffer and after updating stty pendin, to get this input from the buffer and print it on the screen.

Is there a Linux equivalent for a function stty pendin? Or maybe you know a bash solution for my problem?

+3
source share
4

, , . :)

:

while :
do
    # print the progress on the screen
    echo -n "Enter command: "
    tput sc # save the cursor position
    echo -n "$tmpBuffer" # this is buffer which holds typed text (no 'ENTER' key yet)
    waitForUserInput
    read arguments <<< $(echo $mainBuffer) # this buffer is set when user presses 'ENTER'
    mainBuffer="" # don't forget to clear it after reading
    # now do the action requested in $arguments
done

waitForUserInput 10 . - , . , ( ). , :

function waitForUserInput {
    saveIFS=$IFS # save current IFS
    IFS="" # change IFS to empty string, so 'ENTER' key can be read

    while :
    do
        read -t10 -n1 char
        if (( $? == 0 ))
        then
            # user pressed something, so parse it
            case $char in
                $'\b')
                    # remove last char from string with sed or perl
                    # move cursor to saved position with 'tput rc'
                    echo -n "$tmpBuffer"
                    ;;
                "")
                    # empty string is 'ENTER'
                    # so copy tmpBuffer to mainBuffer
                    # clear tmpBuffer and return to main loop
                    IFS=$saveIFS
                    return 0
                    ;;
                 *)
                    # any other char - add it to buffer
                    tmpBuffer=$tmpBuffer$char
                    ;;
            esac
        else
            # timeout occured, so return to main function
            IFS=$saveIFS
            return 1
        fi
    done
}

!

+1

, ... read -n1, , . , , 15- ...


:

/ - IFS , , ,

:

XIFS="${IFS}"  # backup IFS
IFS=$'\r'      # use a character your user is not likely to enter (or just the same but w/o the space)


# Enter will look like en empty string
$ read -n1 X; echo --; echo -n "${X}" | od -tx1

--
0000000


# space will be presented as a character
$ read -n1 X; echo --; echo -n "${X}" | od -tx1
 --
0000000 20
0000001


# after you are all done, you probably wantto restore the IFS
IFS="${XIFS}"
+2

, @nhed, , - :

#!/bin/bash

limit=5

draw_screen () {
    clear;
    echo "Elapsed time: $SECONDS" # simulate progress indicator
    printf 'Enter command: %s' "$1"
}

increment=$limit
str=
end=0
while ! [ $end -eq 1 ] ; do
    draw_screen "$str"
    while [ $SECONDS -lt $limit ] && [ $end -eq 0 ] ; do
            c=
            IFS= read -t $limit -r -n 1 -d '' c
            if [ "$c" = $'\n' ] ; then
                    end=1
            fi
            str="${str}${c}"
    done
    let limit+=increment
done
str="${str%$'\n'}" # strip trailing newline

echo "input was: '$str'"

:

  • - ( ).

, , .

+1

Bash 4:

read -p 'Enter something here: ' -r -t 15 -e -i "$myVar" myVar

-eincludes readline support for entering user text. -iuses the following text as the default content of the input buffer that it displays to the user. The next text in this case is the previous contents of the variable you are reading.

Demonstration:

$ myVar='this is some text'    # simulate previous entry
$ read -p 'Enter something here: ' -r -t 15 -e -i "$myVar" myVar
Enter something here: this is some text[]

Where []represents the cursor. If necessary, the user will be able to return and correct the previous text.

+1
source

All Articles