Stopping the script by clicking a specific button (listen to STDIN when the script is handling it)

There is a script that interacts with the user using the press y / n dialog (ie stdin is already in use). By pressing the button of the predefined keyboard, the main script should interrupt its operation.

I tried to implement it in two ways, by reading and using grep (ah, and also trying to use stty-stty -echo -icanon time 0 min 0, but it didn't work overall).

The problem with grep (grep -q) is that the main thread goes in a loop with grep (which I looped to constantly check stdin), while I need the main script to listen to STDIN for a specific keypress. Considering that it finally turned into such a small piece:

breakByButton()
{
while ! [ "$z" = "11" ]
do
    read -t 1 -n 1 key

    if [[ $key = <desired key> ]]
    then
        echo -e "\n\e[31mStopped by user\e[0m"
        break
    fi
done
}

      

Of course, this function also only works where it was called. As a separate script in the background and also with grep, execution breaks after the first press of Enter. Now I am thinking of a parallel process - script and reading, but haven't made a decision yet.

+3


source to share


2 answers


This is why there are interrupts. If you want to terminate a process that is otherwise using stdin, enter ctrl-C. This interrupts the process and optionally transfers control to the interrupt handler. For example, in this script, it MyExit

functions as an interrupt handler. If you run this script and type Ctrl-C, execution will stop and your desired message will appear:

MyExit() {
    echo -e "\n\e[31mStopped by user\e[0m"
    exit
}    
trap MyExit INT

while true
do
    # do something important that captures stdin
    cat >/dev/null
done

      



In practice MyExit

should also do whatever is necessary to clean up after the script execution is interrupted. This often includes deleting temporary files, for example.

A key feature of this approach works even when stdin is already in use. It does not require waiting until stdin is available.

+1


source


While you havent absolutely no idea what you really need , try the following demo (click q

to exit)



trap 'stty sane;exit' 0 2

do_quit() {
    echo -e "Quit....\r" >&2
    return 1
}

do_something() {
    echo -e "Doing something after the key: $key\r"
}

inkey() {
    stty raw
    while :
    do
        read -t 1 -n 1 key
        case "$key" in
            q|Q) do_quit || exit ;;
            '') ;; #nothing
            *) do_something "$key" ;;
        esac
    done
}

#main
inkey

      

+1


source







All Articles