【问题标题】:handle user input on background在后台处理用户输入
【发布时间】:2011-08-10 17:42:50
【问题描述】:

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

例如,显示一个进度条,当用户点击R时,进度条重置,或者如果用户点击Q,脚本退出。 p>

我不希望脚本等待用户输入。只需渲染所有内容,如果用户按任意键执行操作。

在 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:对不起,我的最后一条评论,时间编辑在我的编辑中完成

【问题讨论】:

  • @user719946 您可能需要澄清您要做什么。如果后台作业尝试从终端读取,它们将被暂停。我在谷歌搜索“bash non-blocking io”时得到了一些结果,这就是你想要做的吗?另外,主题不用加[bash],tag就够了。
  • @andy 感谢您的回答。我正在做一些像乒乓球游戏一样的脚本。球更新运动在一个主循环中(虽然确实如此)。因此,读取输入(移动调色板)会阻止球的运动,因为要等到用户按下任何键。希望你能理解我。对不起 [bash] 并且没有用户名;这是我的第一个问题。

标签: bash input background


【解决方案1】:

这是一种似乎有效的技术。我基于 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 声明来解决这个问题。

【讨论】:

  • 在你的脚本中,当按下一个键时循环结束。我已经更新了我的第一篇文章,向您展示了我的脚本。
  • @jotapdiez 我更新了示例。我不确定这在慢速终端上的效果如何,多字节序列可能会被破坏。但这应该很接近。
  • 有效!!我做了一些其他的事情来让它更好地工作,但你的答案很好。谢谢。 (我不能投票,因为需要更多代表,抱歉)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    相关资源
    最近更新 更多