内容简介:相信各位读者对秒表都不陌生,智能手机上通常都有这样一款软件有一天心血来潮,便想要“复刻”一个命令行版本的秒表程序——主要是想尝试一下新学会的、“原地更新”的技能,而不是一行接一行地输出。程序的运行效果如下
相信各位读者对秒表都不陌生,智能手机上通常都有这样一款软件
有一天心血来潮,便想要“复刻”一个命令行版本的秒表程序——主要是想尝试一下新学会的、“原地更新”的技能,而不是一行接一行地输出。程序的运行效果如下
那么这是怎么做的呢?
实现思路及代码
如何获取流逝的时间长度?
要实现一个秒表,首先要知道从开始计时至今过了多久。在*nix系统中,表示时刻的事实标准是 Epoch Time ,在 shell
脚本中要获取Epoch Time可以用 date
命令。再用首尾时刻相减便得到了期间流逝的秒数了,示例代码如下
begin_at=$(date '+%s') # 睡个觉 end_at=$(date '+%s') ((interval=${end_at} - ${begin_at}))
双圆括号是一种在 shell
脚本中执行算术运算的语法,其它语法可以参见 Math in Shell Scripts 。
如何换算为时分秒?
有了 interval
中存储的总秒数后,换算成时分秒便是轻而易举的事情,示例代码如下
((hours=${interval} / 3600)) ((minutes=(${interval} % 3600) / 60)) ((seconds=(${interval} % 3600) % 60))
如何输出形如 hh:mm:ss
的格式?
hh:mm:ss
的意思是分别用两个十进制数字显示时分秒,并以冒号分隔它们。如果有任何一个单位的数值小于10,便用字符 0
填充左侧的空白。按这个格式,凌晨1点2分3秒便会显示为 01:02:03
。
要在命令行中打印字符串,最容易想到的便是 echo
命令,只可惜它不能方便地实现填充字符 0
的需求。
强人所难也不是不行,示例代码如下
hours=1 minutes=2 seconds=3 if [ "${hours}" -lt '10' ]; then echo -n "0${hours}" else echo -n "${hours}" fi echo -n ':' if [ "${minutes}" -lt '10' ]; then echo -n "0${minutes}" else echo -n "${minutes}" fi echo -n ':' if [ "${seconds}" -lt '10' ]; then echo -n "0${seconds}" else echo -n "${seconds}" fi
更优雅的方法是用 printf
命令来自动填充左侧的字符 0
printf "%02d:%02d:%02d" ${hours} ${minutes} ${seconds}
printf
命令类似于 C语言 中的 printf
函数——它也支持打印转义的字符,下文会提到。
如何覆盖已经打印的内容?
今年以来我在断断续续地看 Build Your Own Text Editor ,学习如何开发文本编辑器。在这本小册子的 第三章 中,作者讲述了如何使用终端的转义序列( escape sequence
)来控制屏幕上显示的东西——这正是秒表程序所需要的。
例如,在终端输出转义序列 \x1b[2J
可以清空屏幕,效果如下
为了覆盖已经打印出来的时分秒,需要:
- 先将光标移动到行首;
- 再清除从光标开始到行末的内容。
查阅 《VT100 User Guide》第三章 可以知道
- 要把光标移动到行首可以用转义序列
\x1b[8D
。之所以是8,是因为按照hh:mm:ss
输出时分秒后光标距离行首8个身位; - 要清除光标到行末内容可以用转义序列
\x1b[0K
(实际上,将光标移到行首只需要使用回车(carriage return
)即可,但它被解释为开启新的一行了)。
更优雅的方法甚至连转义序列也不需要,只要用 tput
命令即可,示例代码如下
echo -n '11:22:33' tput cr tput el echo '44:55:66'
关于 cr
和 el
,以及更多可以传给 tput
命令的参数,可以参见 terminfo
的 man
文档。
如何每隔一秒钟输出一次?
这大概是整个程序中最简单的需求了
while [ 1 -eq 1 ] do # 此处可以为所欲为 sleep 0.5 done
完整的秒表实现
至此,完整的秒表程序就可以实现出来了
#!/bin/bash # 秒表,以hh:mm:ss的格式展示数据 begin_at=$(date '+%s') while [ 1 -eq 1 ] do end_at=$(date '+%s') # 算术运算:http://faculty.salina.k-state.edu/tim/unix_sg/bash/math.html ((interval=${end_at} - ${begin_at})) ((hours=${interval} / 3600)) ((minutes=(${interval} % 3600) / 60)) ((seconds=(${interval} % 3600) % 60)) tput cr tput el printf "%02d:%02d:%02d" ${hours} ${minutes} ${seconds} sleep 0.5 done
运行后的效果正如本文开头的GIF所示。
全文完。
以上所述就是小编给大家介绍的《如何写一个命令行的秒表》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Axure教程:实现秒表循环
- Protopie教程1-2:可交互秒表
- composer更新命令及常用命令
- Linux命令行与命令
- AWK命令和SED命令
- 每天一个 Linux 命令(60): scp命令
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。