我需要显示从20 sec
到 的递减顺序倒计时器00 sec
如果他/她未能在给定的 20 秒内输入密码,则退出并显示消息你的时间结束了
输出 :
you have 20 sec to enter password :
you have 15 sec to enter password :
you have 10 sec to enter password :
you have 00 sec to enter password :
显示消息的部分工作代码
read -t 20 -p 'Enter your password : '
status=$?
if [ $status -eq 142 ]
then
echo "your time is over"
fi
答案1
直到有人想出更好的解决方案:
#!/bin/bash
tmout=20
(
while [[ $tmout -gt 0 ]]; do
printf '\rPlease respond within %02d seconds: ' "$tmout" >&2
sleep 1
tmout=$(( tmout - 1 ))
done
) & prompt_pid=$!
read -s -t "$tmout"
read_ok=$?
echo ''
if [[ $read_ok -eq 0 ]]; then
kill "$prompt_pid"
printf 'You responded with "%s"\n' "$REPLY"
else
echo 'You did not respond in time'
fi
这将启动一个后台作业,该作业每秒更新一次提示,持续$tmout
几秒钟或直到被杀死。提示文本前面有\r
,即回车符。输出\r
withprintf
将光标移回行首,这意味着字符串的其余部分将覆盖之前输出的任何文本,给人一种滴答作响的计数器的印象。我故意使用一个由零填充的两位整数作为计数器,以便输出的文本字符串printf
始终具有相同的长度(至少对于$tmout
小于 100 的值)。
然后,前台作业使用超时等待$tmout
几秒钟以等待用户的输入。read
我在这里使用-s
with是read
因为我们正在读取密码(这也意味着所输入的内容不会被显示,也不会被输出的提示弄乱)。
返回后read
,我们确保终止提示循环(如果它仍在运行),然后根据read
终止方式打印一条消息。
答案2
这是一个片段;当达到 00 秒时,它将等待更多 5 秒,您可以使用条件编辑它,因为我不知道这是否是想要的行为:
#!/bin/bash
c1=5
c2=4
count=20
status=''
while [[ "$count" != 0 ]]
do
count="$(expr $c1 \* $c2)"
c2="$(expr $c2 \- 1)"
read -t 5 -p "You have $count sec to enter your password : "$'\n'
status=$?
if [ "$status" -ne 142 ] ; then
break
fi
done
if [ "$status" -eq 142 ]
then
echo "Your time is over"
else
echo "Success"
fi
###编辑###
输出1:
[root@host~]# ./lol.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
You have 10 sec to enter your password :
You have 5 sec to enter your password :
You have 0 sec to enter your password :
Your time is over
输出 2:
[root@host~]# ./lol.sh
You have 20 sec to enter your password :
LOL
Success
[root@host~]#
## 按照评论中的建议编辑 2 个更多的全球解决方案 ## :
对于这个,计数器正好是 20 秒;你可以改变TMT&等待秒方便时的常量。
#!/bin/bash
##CALCULATTION :
##TIMEOUT=WAIT_SECONDS * NB_ITERATIONS
##TIMEOUT modulo WAIT_SECONDS should equal to 0 to get a fixed iterations number
# 20 = 5 * 4
wait_sec=5
tmt=20
modulo_ok=1
fpr=1
count="$tmt"
# Modulo Test
if [[ "$(($tmt % $wait_sec))" -eq 0 ]]; then
nb_iters="$(expr $tmt \/ $wait_sec)"
modulo_ok=0
fi
if [[ "modulo_ok" -eq 0 ]]; then
(while [[ "$count" != 0 ]] && [[ "$fpr" -gt 0 ]]
do
count="$(expr $wait_sec \* $nb_iters)"
nb_iters="$(expr $nb_iters \- 1)"
echo "You have $count sec to enter your password :"
ps -p "$pid" &> /dev/null
sleep $wait_sec
done
) & fpr=$?
bpr=$!
read -t "$tmt" -s pass
kill $bpr > /dev/null 2>&1
if [[ -z "$pass" ]]
then
echo "Your time is over"
else
echo "Success"
echo "Your password is : $pass"
fi
else
echo 'Timeout modulo Wait seconds should be equal to 0'
fi
输出 3: CASE -> tmt 间隔期间设置的密码
[root@host~]# ./lol2.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
Success
Your password is : Reda
输出 4:案例 -> 超时
[root@host~]# ./lol2.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
You have 10 sec to enter your password :
You have 5 sec to enter your password :
Your time is over
输出 5:CASE -> tmt % wait_sec 不等于 0
[root@host~]# ./lol2.sh
Timeout modulo Wait seconds should be equal to 0