![bash中输入“q”时如何停止读取?](https://linux22.com/image/216256/bash%E4%B8%AD%E8%BE%93%E5%85%A5%E2%80%9Cq%E2%80%9D%E6%97%B6%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2%E8%AF%BB%E5%8F%96%EF%BC%9F.png)
我正在使用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
输入时提前离开)和第二个字符的后续读取(我将它们称为ch1
和ch2
):
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
作为命令运行)