倒计时脚本写完已经有一年了,shell做客户端展示效果的东西不容易,昨天回头看了下可以优化的地方太多了,然后就抽时间优化了以下,从之前442行缩短到现在160行,脚本功能没有少,可读性更强了,现在把新的代码放上来了,哈哈!
#!/bin/bash
#====================================================================
# CREATION TIME: 2019-09-20
# MODIFICATION TIME: 2020-11-11
# AUTHOR: wyp
# USE: Countdown
# COORDINATE: (0,0) (0,1) (0,2)
# (1,0) (1,1) (1,2)
# (2,0) (2,1) (2,2)
# (3,0) (3,1) (3,2)
# (4,0) (4,1) (4,2)
#
#===================================================================
function f_print_coordinate
{
num0=(0 0 0 1 0 2 1 0 1 2 2 0 2 2 3 0 3 2 4 0 4 1 4 2)
num1=(0 1 1 1 2 1 3 1 4 1)
num2=(0 0 0 1 0 2 1 2 2 2 2 1 2 0 3 0 4 0 4 1 4 2)
num3=(0 0 0 1 0 2 1 2 2 2 2 1 2 0 3 2 4 2 4 1 4 0)
num4=(0 0 1 0 2 0 2 1 2 2 0 2 1 2 3 2 4 2)
num5=(0 2 0 1 0 0 1 0 2 0 2 1 2 2 3 2 4 2 4 1 4 0)
num6=(0 0 0 1 0 2 1 0 2 0 2 1 2 2 3 0 4 0 4 1 4 2 3 2)
num7=(0 0 0 1 0 2 1 2 2 2 3 2 4 2)
num8=(0 0 0 1 0 2 1 0 1 2 2 0 2 1 2 2 3 0 3 2 4 0 4 1 4 2)
num9=(0 0 0 1 0 2 1 0 1 2 2 0 2 1 2 2 3 2 4 2 4 1 4 0)
colon=(1 1 3 1 )
}
function f_print_red {
echo -e "\033[1;31m$1\033[0m"
}
function f_print_yellow {
echo -ne "\033[1;33m$1\033[0m"
}
function f_judge_value
{
if [ "${1}" == 0 ]; then value=${num0[*]}
elif [ "${1}" == 1 ]; then value=${num1[*]}
elif [ "${1}" == 2 ]; then value=${num2[*]}
elif [ "${1}" == 3 ]; then value=${num3[*]}
elif [ "${1}" == 4 ]; then value=${num4[*]}
elif [ "${1}" == 5 ]; then value=${num5[*]}
elif [ "${1}" == 6 ]; then value=${num6[*]}
elif [ "${1}" == 7 ]; then value=${num7[*]}
elif [ "${1}" == 8 ]; then value=${num8[*]}
elif [ "${1}" == 9 ]; then value=${num9[*]}
elif [ "${1}" == ":" ]; then value=${colon[*]}
fi
number=${1}${1}
echo ${value} ${number}
}
function f_print
{
if echo ${time} | gawk -F: '{print $1}' | grep -oqE [[:digit:]]{3}; then #判断需要倒计时的时间分钟位是否是3位数
left=86
time_array=($(echo ${time} | sed -r 's/(.)(.)(.)(.)(.)(.)/\1 \2 \3 \4 \5 \6/')) # 处理时间变量,将其转换为数组
else
left=93
time_array=($(echo ${time} | sed -r 's/(.)(.)(.)(.)(.)/\1 \2 \3 \4 \5/'))
fi
top=28
t=0
for time_element in ${time_array[*]}; do
if [ "${#time_array[*]}" -eq 5 ];then #根据数组的元素个数和位置来控制输出的颜色
if [ "${t}" -eq 1 -o "${t}" -eq 4 ];then
colour_num=32
elif [ "${t}" -eq 2 ];then
colour_num=35
else
colour_num=31
fi
else
if [ "${t}" -eq 0 ];then
colour_num=33
elif [ "${t}" -eq 3 ];then
colour_num=35
elif [ "${t}" -eq 2 -o "${t}" -eq 5 ];then
colour_num=32
else
colour_num=31
fi
fi
array_value=($(f_judge_value ${time_element})) #判断数组的值对应的坐标,返回坐标与传入f_judge_value函数判断的值,例如传入1,返回11
number_displayed=${array_value[${#array_value[*]}-1]} #提取传入f_judge_value函数判断的值,例如传入1,返回11
unset array_value[${#array_value[*]}-1] #删除数组的最后一个元素,也就是上面所说的传入f_judge_value函数判断的值
# 显示颜色
echo -e "\033[1;${colour_num}m"
for((j = 0,i = 1;j < ${#array_value[@]};i=i+2,j=j+2)); do #根据坐标来打印输出,组合成为数字图形
((x = left+2*${array_value[i]}))
((y = top+${array_value[j]}))
echo -e "\033[${y};${x}H${number_displayed}"
done
##恢复颜色
echo -e "\033[0m"
let t++
let left+=7 #控制光标左右移动的位置,top控制的是上下移动的位置,不用动,所以只需要控制left的值
done
}
function f_print_zero
{
echo -e "\033[1;31m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
000000 000000 000000 000000
00 00 00 00 :: 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 :: 00 00 00 00
000000 000000 000000 000000
\033[0m"
echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
##########################################################################################################################################
#cd $(dirname `/usr/sbin/lsof -p $$ | gawk '$4 =="255r"{print $NF}'`) #进入脚本当前所在的目录,这个需要先安装lsof命令才能使用
# 输入且判断参数
while true; do
f_print_yellow "输入倒计时时间(分钟):"
read minute
f_print_yellow "输入倒计时时间(秒钟):"
read second
minute=${minute:-0} #定义变量的初始值
second=${second:-0}
check_minute=`echo ${minute} | sed -r 's/[[:digit:]]+//'` #将数字删除,如果变量不为空,则说明还有其他的字符,也就是输入不正确
check_second=`echo ${second} | sed -r 's/[[:digit:]]+//'`
if [ ! -z "${check_minute}" -o ! -z "${check_second}" ]; then
f_print_red "注意: 输入只能是数字,不能含有英文,标点符号,空格或者控制字符\n"
else
total_seconds=$[${minute}*60+${second}]
if [ "${total_seconds}" -gt 59999 ];then
f_print_red "注意: 本倒计时脚本最高支持倒计时999分钟59秒, 也就是一共999*60+59=59999秒钟\n"
else
break
fi
fi
done
f_print_coordinate
echo -e "\033[?25l" #隐藏光标
# 进入倒计时循环
while [ ${total_seconds} -gt 0 ]; do
min=$[${total_seconds}/60]
sec=$[${total_seconds}%60]
# 格式化输出时间,保证输出都是两位数以上
if [ ${min} -lt 10 ];then min=$(printf %02d ${min}); fi
if [ ${sec} -lt 10 ];then sec=$(printf %02d ${sec}); fi
clear
time="${min}:${sec}"
f_print
sleep 1
let total_seconds-=1
done
clear
f_print_zero
echo -e "\033[?25h" #显示光标