bash中输入“q”时如何停止读取?

bash中输入“q”时如何停止读取?

我正在使用read用户输入来执行某些操作。选择器使用两个字符测试来打印适当的信息,而不需要用户ENTER在输入后按。是否可以接受q要退出的值,因为它不是由两个字符选择器组成。

  local done="false"
  while [ "$done" != "true" ]
  do
    echo ; read -n 2 lsk
    case $lsk in
     "1L")
        echo "$navaid_vscal"
        echo -e "$tacrgm"
        ;;
     q)
        done="true"  # ends while loop
        echo -n "$sgr"
        ;;
     *)
        ## repeats while do
        ;;
    esac
  done

答案1

我不相信read内置的 bash 具有该功能。但是您可以实现自定义读取命令或者功能为了实现这一点。

例如,您可以使用此功能:

read_or_quit(){
x=0;
while ((++x<=2)); do 
   read -n 1

   if [[ $REPLY = q ]]; then 
      echo q
      break
   else 
     echo -n "$REPLY"
   fi
done ; 
echo

# I thought that printing `echo` to `stdout` would
# append a new line which might break the `case` 
# functionality.
# echo >&2
}

您可以通过$(read_or_quit)在代码中使用来调用该函数:

local done="false"
  while [ "$done" != "true" ]
  do
    lsk=$(read_or_quit)
    case $lsk in
     "1L")
        echo "$navaid_vscal"
        echo -e "$tacrgm"
        ;;
     q)
        done="true"  # ends while loop
        echo -n "$sgr"
        ;;
     *)
        ## repeats while do
        ;;
    esac
  done

答案2

将读取分为初始读取(q输入时提前离开)和第二个字符的后续读取(我将它们称为ch1ch2):

local done=false
until "$done"
do
    echo
    read -n 1 ch1
    if [ ch1 = q ]
    then
        printf %s "$sgr"  # More portable than echo -n
        break
    fi
    read -n 1 ch2
    case "$ch1$ch2" in
        1L)
            echo "$navaid_vscal"
            echo -e "$tacrgm"  # portability problem here!
            ;;
        *)
            ## repeats while do
            ;;
    esac
done

显然,循环可以是while true因为现在没有设置done,但也许您需要在其中一个case块中使用它,所以我保留了它。 (为了简单起见,我确实将字符串相等性测试更改为仅$done作为命令运行)

相关内容