BASH - 定时输入 - 显示倒计时

时间:2016-01-15 14:49:35

标签: bash input

我有一个bash脚本,要求用户提供详细信息。

我设置了等待输入时间的限制。我发现了这个,看起来就像我想要的那样。

timelimit=5
echo -e " You have $timelimit seconds\n Enter your name quickly: \c"
name=""
read -t $timelimit name
#read -t $timelimit name <&1 
# for bash versions bellow 3.x
if [ ! -z "$name" ]
then
echo -e "\n Your name is $name"
else
echo -e "\n TIME OUT\n You failed to enter your name"
fi 

它显示&#34;你有5秒......&#34;任何更新输出的方法,因此它会倒计时显示4,3,2,1等?

由于

6 个答案:

答案 0 :(得分:2)

这应该有效,不应该覆盖输入,比其他解决方案更长时间。

#!/bin/bash

abend() 
{       
        stty sane
        exit
        #Resets stty and then exits script
}

DoAction(){

        stty -echo 
        #Turn off echo
        tput sc
        #Save cursor position
        echo -ne "\033[0K\r"
        # Remove previous line
        tput cuu1
        #Go to previous line
        tput el
        #clear to end of line
        echo "You have $(($time-$count)) seconds"
        #Echo timer
        echo -n "$Keys"
        #Echo currently typed text
        stty echo
        #turn echo on
        tput rc
        #return cursor
}


main()
{
trap abend SIGINT # Trap ctrl-c to return terminal to normal
stty -icanon time 0 min 0 -echo
#turn of echo and set read time to nothing
keypress=''

time=5
echo "You have $time seconds"
while Keys=$Keys$keypress; do
        sleep 0.05
        read keypress && break
        ((clock  = clock + 1 ))
        if [[ clock -eq 20 ]];then
                ((count++))
                clock=0
                DoAction $Keys
        fi
        [[ $count -eq $time ]] && echo "you have run out of time" && abend



done

stty sane
echo Your username was $Keys
echo "Thanks for using this script."
exit 0
}

main

答案 1 :(得分:1)

这似乎有效:

$ cat test.sh 
total=5  # total wait time in seconds
count=0  # counter
while [ ${count} -lt ${total} ] ; do
    tlimit=$(( $total - $count ))
    echo -e "\rYou have ${tlimit} seconds to enter your name: \c"
    read -t 1 name
    test ! -z "$name" && { break ; }
    count=$((count+1))
done
if [ ! -z "$name" ] ; then
    echo -e "\nyour name is $name"
else
    echo -e "\ntime out"
fi

答案 2 :(得分:1)

#!/bin/bash

timelimit=6
name=""

for (( i = 1 ; i <= $timelimit; i++ )); do
        echo -ne "\rYou have $(expr $timelimit - $i) seconds. Enter your name quickly: \c"
        [ ! -z "$name" ] && { break ; }
        read -t 1 name
done

if [ -z "$name" ]; then
        echo -e "\n TIME OUT\n You failed to enter your name"
else
        echo -e "\n Your name is $name"
fi

这应该有效

答案 3 :(得分:1)

这对我来说很好,也很快:

#!/bin/bash
#Sets starttimestamp
starttime=$(date +%s)
#Sets timeout
timeout=5
#sets successflag default to false
success=false

#Save Cursorposition
echo -n -e "\033[s"

#While time not up
while [ $(($starttime+$timeout)) -gt $(date +%s) ] ; do
        #Return to saved Cursorpositon
        echo -n -e "\033[u"
        #Display time left
        echo "$(((starttime+timeout)-$(date +%s))) seconds left"
        #Ask for 1 char then go on in loop make it look like an ongoing input by adding the user variable to the prompt
        if read -p foo="Username: $user" -n 1 -t 1 c ; then
                #If user hits return in time c will be empty then break out of loop and set success true
                if [[ $c == "" ]] ; then
                        success=true
                        break
                fi
                # Append latest character to user variable
                user=${user}${c}
                unset c
        fi
done

if $success ; then
        echo "Yiha!"
else
        echo "Too late!"
fi

答案 4 :(得分:0)

我建议使用一个打印出你有秒数的循环,然后睡一秒钟。这会给你你想要的东西。

或者你可以编写5个打印语句,在每个语句之间有一个休眠1秒的函数,并在每个打印行之后将$ timelimit变量减1。

这是一个很棒的链接,可以满足您的需求。 http://www.cyberciti.biz/faq/linux-unix-sleep-bash-scripting/

答案 5 :(得分:0)

我已经尝试了大多数答案,但都没有一个对我来说很完美。
正在针对本地开发人员部署脚本使用此功能。
这样可以解决一些提到的问题,例如打印输出等。
还具有可移植性。我渴望看到任何改进。

这是我的解决方法:

#!/bin/bash
# set -euo pipefail

READTIMEOUT=5

function read_yn {
    MESSAGE=$1
    TIMEOUTREPLY=$2
    NORMALREPLY="Y"
    if [ -z "${TIMEOUTREPLY}" ]; then
        TIMEOUTREPLY="Y"
    fi
    TIMEOUTREPLY_UC=$( echo $TIMEOUTREPLY | awk '{print toupper($0)}' )
    TIMEOUTREPLY_LC=$( echo $TIMEOUTREPLY | awk '{print tolower($0)}' )
    if [ "${TIMEOUTREPLY_UC}" == "Y" ]; then
        NORMALREPLY="N"
    fi
    NORMALREPLY_UC=$( echo $NORMALREPLY | awk '{print toupper($0)}' )
    NORMALREPLY_LC=$( echo $NORMALREPLY | awk '{print tolower($0)}' )
    for (( i=$READTIMEOUT; i>=0; i--)); do
        printf "\r${MESSAGE} [${NORMALREPLY_UC}${NORMALREPLY_LC}/${TIMEOUTREPLY_UC}${TIMEOUTREPLY_LC}] ('${TIMEOUTREPLY_UC}' in ${i}s) "
        read -s -n 1 -t 1 waitreadyn
        if [ $? -eq 0 ]
        then
            break
        fi
    done
    yn=""
    if [ -z $waitreadyn ]; then
        echo -e "\nNo input entered: Defaulting to '${TIMEOUTREPLY_UC}'"
        yn="${TIMEOUTREPLY_UC}"
    else
        echo -e "\n${waitreadyn}"
        yn="${waitreadyn}"
    fi
}

read_yn "TESTING" "y"

GIST: https://gist.github.com/djravine/7a66478c37974940e8c39764d59d35fa

实时演示: https://repl.it/@DJRavine/read-input-with-visible-countdownsh