使用shell实现loading加载效果-tput

先放一张效果图:

loading效果图

实现效果图中的效果,我们大量使用了命令tput,这篇文章中我们会详细介绍tput命令。

什么是 tput?

man手册这么说道:

tput 命令将通过 terminfo 数据库对您的终端会话进行初始化和操作。通过使用 tput,您可以更改几项终端功能,如移动或更改光标、更改文本属性,以及清除终端屏幕的特定区域。

什么是 terminfo 数据库?

man手册这么说道:

UNIX 系统上的 terminfo 数据库用于定义终端和打印机的属性及功能,包括各设备(例如,终端和打印机)的行数和列数以及要发送至该设备的文本的属性。UNIX 中的几个常用程序都依赖 terminfo 数据库提供这些属性以及许多其他内容,其中包括 vi 和 emacs 编辑器以及 curses 和 man 程序。

tput 命令行简介

与 UNIX 中的大多数命令一样,tput 命令既可以用在 shell 命令行中也可以用在 shell 脚本中。

tput最常用也是最简单的用法为:Usage: tput capname

其中capname为对终端要进行的各种操作,具体有哪些capname,我们可以通过命令

man terminfo.5

查询到,其中如果capname的类型为string(terminfo有定义各个capname是什么类型),则terminfo会返回其对应的控制代码在output中(结尾不跟换行符),如果类型为int也会返回控制代码在output中(结尾跟换行符),如果类型为bool则会返回在状态码中。

光标属性

在 UNIX shell 脚本中或在命令行中,移动光标或更改光标属性可能是非常有用的。有些情况下,您可能需要输入敏感信息(如密码),或在屏幕上两个不同的区域输入信息。在此类情况下,使用 tput 可能会对您有所帮助。

移动光标

使用 tput 可以方便地实现在各设备上移动光标的位置。通过在 tput 中使用 cup 选项,或光标位置,您可以在设备的各行和各列中将光标移动到任意 X 或 Y 坐标。设备左上角的坐标为 (0,0)。

要在设备上将光标移动到第 5 列 (X) 的第 1 行 (Y),只需执行 tput cup 5 1。另一个示例是 tput cup 23 45,此命令将使光标移动到第 23 列上的第 45 行。

tput 命令

tput 可以更改终端功能,如移动或更改光标,更改文本属性,清除终端屏幕的特定区域等。

光标属性

在 shell 脚本或命令行中,可以利用 tput 命令改变光标属性,更多查询terminfo。

tput clear # 清除屏幕
tput sc # 记录当前光标位置
tput rc # 恢复光标到最后保存位置
tput civis # 光标不可见
tput cnorm # 光标可见
tput cup x y # 光标按设定坐标点移动

利用上面参数编写一个终端时钟

#!/bin/bash

for ((i=0;i<10;i++))
do
tput sc; tput civis # 记录光标位置,及隐藏光标
echo -ne $(date +'%Y-%m-%d %H:%M:%S') # 显示时间
sleep 1
tput rc # 恢复光标到记录位置
done

tput el; tput cnorm # 退出时清理终端,恢复光标显示,未处理突然退出的情况

效果如图

文本属性

tput可使终端文本加粗、在文本下方添加下划线、更改背景颜色和前景颜色,以及逆转颜色方案等。

tput blink # 文本闪烁
tput bold # 文本加粗
tput el # 清除到行尾
tput smso # 启动突出模式
tput rmso # 停止突出模式
tput smul # 下划线模式
tput rmul # 取消下划线模式
tput sgr0 # 恢复默认终端
tput rev # 反相终端

此外,还可以改变文本的颜色

tput setab 颜色代号
tput setaf 颜色代号

# tput setb
# tput setf
# 这个两个命令似乎也可以设置颜色,由于其诞生较早,其转义码不是ascii码规范(\033[),在我的终端不起作用

颜色代号为

0:黑色
1:蓝色
2:绿色
3:青色
4:红色
5:洋红色
6:黄色
7:白色

现在为"终端时钟"添加,变换颜色和闪烁功能

#!/bin/bash

for ((i=0;i<8;i++))
do
tput sc; tput civis # 记录光标位置,及隐藏光标
tput blink; tput setaf $i # 文本闪烁,更改文本颜色
echo -ne $(date +'%Y-%m-%d %H:%M:%S') # 显示时间
sleep 1
tput rc # 恢复光标到记录位置
done

tput el; tput cnorm # 退出时清理终端,恢复光标显示

TL;DR

回到我们标题,灵活运用上述提到的功能即可。

注意\r\n是通用的文本控制符,可以将光标置行首。

直接放shell代码:

#! /bin/bash

Loading_Sentence="Loading"
Finish_Sentence="Done!"

# 保存当前光标状态; 隐藏光标
tput sc; tput civis

for ((i=0; i < 3; i ++));do
s=$Loading_Sentence
echo -n $s
for ((j=0; j<4; j++)); do
sleep 0.5
echo -n '.'
done
tput el1 # 删除从当前光标位置到行首位置直接的所有文字
echo -ne '\r' # 将当前光标移到行首
done

# 恢复当前光标至之前保存的位置;恢复光标
tput rc; tput cnorm

echo $Finish_Sentence