在“ answer=$( while !head -c 1 | grep -i '[ny]' ; do true ; done ) ”处支持 Ctrl+C / Ctrl+Z

Support for Ctrl+C / Ctrl+Z at " answer=$( while ! head -c 1 | grep -i '[ny]' ; do true ; done ) "

为了获得用户的 [Y/N] 决定,我使用 "yesno" 函数,其中包含一个循环:

answer=$( while ! head -c 1 | grep -i '[ny]' ; do true ; done )

但是,此循环正在阻塞控制台并且无法通过按 Ctrl + C Ctrl [ 来终止=27=]+Z。添加诸如 [\x03] Ctrl + C 的 ascii)或 [\x1A] Ctrl 的 ascii + Z ) 也无济于事。如何添加此功能,同时保持 POSIX 兼容性且不依赖其他工具?

#!/bin/sh

yesno () {
    printf " [Y/N] "
    old_stty_cfg=$( stty -g )
    stty raw -echo
    answer=$( while ! head -c 1 | grep -i '[ny]' ; do true ; done )
    stty "$old_stty_cfg"
    if printf "$answer" | grep -iq "^y" ; then
        return 0
    else
        return 1
    fi
}

if yesno "Question?" ; then
    printf "yes\n"
    return 0
else
    printf "no\n"
    return 1
fi

对此解决方案及其 POSIX 兼容性的评论 - 将不胜感激!

#!/bin/sh
enter=$( printf '5' )
ctrl_c=$( printf '[=10=]3' )
ctrl_x=$( printf '0' )
ctrl_z=$( printf '2' )

yesno () {
    printf '%b [Y/N] ' ""
    old_stty_cfg=$( stty -g )
    stty raw -echo
    while true ; do
        answer=$( head -c 1 )
        case $answer in *"$ctrl_c"*|"$ctrl_x"*|"$ctrl_z"*)
            stty "$old_stty_cfg"
            exit 1
            ;;
            *"y"*|"Y"*)
            stty "$old_stty_cfg"
            return 0
            ;;
            *"n"*|"N"*)
            stty "$old_stty_cfg"
            return 1
            ;;
        esac
    done
}

if yesno "Question?" ; then
    printf "yes\n"
    exit 0
else
    printf "no\n"
    exit 1
fi