2011-04-22 92 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

您也可以在腳本末尾添加「重置」以將終端重置爲原始狀態,或者它可能看起來鎖定。它也會清除屏幕,所以在執行命令之前可能需要添加暫停。