我想处理用户输入,但在后台,就像在新线程中一样。
例如,显示进度条,当用户点击 R 时,进度条会重置,或者如果用户点击 Q ,脚本将退出。
我不希望脚本等待用户输入。只需渲染所有内容,如果用户点击任何键,则执行某些操作。
它在bash中是否可行?
提前致谢。
编辑:我需要脚本始终读取用户输入,但不要中断主循环的执行。复杂我自己用英语理解
_handle_keys()
{
read -sn1 a
test "$a" == `echo -en "\e"` || continue
read -sn1 a
test "$a" == "[" || break
read -sn1 a
case "$a" in
C) # Derecha
if [ $PALETTE_X -lt $(($COLUMNS-$PALETTE_SIZE)) ] ; then
PALETTE_X=$(($PALETTE_X+1))
fi
;;
D) # Izquierda
if [ $PALETTE_X -gt 0 ] ; then
PALETTE_X=$(($PALETTE_X-1))
fi
;;
esac
}
render()
{
clear
printf "\033[2;0f BALL (X:${BALL_X} | Y:${BALL_Y})"
_palette_render # Actualiza la paleta
_ball_render
}
while true
do
LINES=`tput lines`
COLUMNS=`tput cols`
render
_handle_keys
done
在我的脚本中,只有在按下某个键时,球才会移动(render
> _ball_render
)因为_handle_keys
等待用户输入。
我用read -t0.1
制作了一个丑陋的解决方案,但不喜欢这个
PD:抱歉我的上一次评论,编辑过程中的时间编辑完成
答案 0 :(得分:7)
这是一种似乎有效的技术。我的基础是Sam Hocevar对Bash: How to end infinite loop with any key pressed?的回答。
#!/bin/bash
if [ ! -t 0 ]; then
echo "This script must be run from a terminal"
exit 1
fi
stty -echo -icanon time 0 min 0
count=0
keypress=''
while true; do
let count+=1
echo -ne $count'\r'
# This stuff goes in _handle_keys
read keypress
case $keypress in
# This case is for no keypress
"")
;;
$'\e[C')
echo "derecha"
;;
$'\e[D')
echo "izquierda"
;;
# If you want to do something for unknown keys, otherwise leave this out
*)
echo "unknown input $keypress"
;;
esac
# End _handle_keys
done
stty sane
如果错过stty sane
(例如因为脚本被 Ctrl - C 杀死),终端将处于奇怪的状态。您可能需要查看trap
语句来解决此问题。
答案 1 :(得分:1)
您还可以在脚本末尾添加“reset”以将终端重置为原始状态,或者它可能看起来已锁定。它也会清除屏幕,因此可能需要在执行命令之前添加暂停。