2011-04-22 49 views
5

我想处理用户输入,但在后台,就像在一个新线程中。在后台处理用户输入

例如,显示一个进度条,并且当​​用户点击- [R,进度条复位,或者如果用户点击Q,脚本退出。

我不希望脚本等待用户输入。只需渲染所有内容,如果用户点击任意键就可以做点什么。

它在bash中是否可行?

在此先感谢。

编辑:我需要剧本,一定要先阅读用户输入,但不中断主要loop.Complicated的执行我让自己在英语

_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

@ user719946您可能需要澄清您要做的事情。如果他们尝试从终端读取,后台作业将被暂停。我得到了一些搜索“bash non-blocking io”的搜索结果,那是你想要做什么的?另外,不需要在主题中加入[bash],标签就足够了。 – Andy 2011-04-22 03:19:14

+0

@andy thx为您的答案。我正在做一些脚本,比如乒乓球比赛。球更新运动是在一个主循环(虽然是真的)。因此,读取输入(移动调色板)会阻止球的移动,因为等待用户敲击任何键。希望你能理解我。对不起[bash]和没有用户名;这是我的第一个问题。 – jotapdiez 2011-04-22 04:21:56

回答

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杀死 - Ç),终端将在一个奇怪的状态下放置。你可能想看看trap声明来解决这个问题。

+0

在您的脚本中,循环在按下按键时结束。我更新了我的第一篇文章,向您展示我的剧本。 – jotapdiez 2011-04-22 18:36:45

+0

@jotapdiez我更新了这个例子。我不确定这将在慢速终端上运行得如何,多字节序列可能会被打破。但这应该是接近的。 – Andy 2011-04-22 19:26:10

+0

作品!我做了一些其他的事情,使它更好地工作,但你的答案工作正常。谢谢。 (我不能投票,因为需要更多的代表,对不起) – jotapdiez 2011-04-22 21:21:24

1

您也可以在脚本末尾添加“重置”以将终端重置为原始状态,或者它可能看起来锁定。它也会清除屏幕,所以在执行命令之前可能需要添加暂停。