多年程序员总结下来的懒人必备脚本之进度条⚠️制作

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

制作进度条

  • 最近正在制作一些脚本方便平时重复的工作。毕竟不能白瞎了自己的mac电脑。制作至于发现别人家的脚本可都是自带进度条的。说干就干我就准备研究下进度条怎么搞

image-20220601153829228.png

  • 先看下我们的效果图

image-20220601154309747.png

image-20220601154326037.png

image-20220601154338137.png

思考

  • 既然是进度条,那么首先一点我们的输出肯定是不能换行的。不换行的方式我们可以echo -ne ">"这样来。但是我在mac上shell脚本里执行的是这样的效果
 for i in {1..100}
 do
         echo -ne  ">"
         echo -ne h
         #if [ $i -eq 2 ]
         #then
         #    break
         #fi
         sleep 1
 done
复制代码

image-20220601154537472.png

  • 很明显echo -ne在shell里并没有搞出来。还请大佬指点
  • 既然这种不行我们就换另外方式。和C语言一样在Linux中输出内容也可以利用printf

image-20220601154727571.png

  • 而我们常见的进度条无非这种结构

image-20220601155413814.png

printf

  • 我们看看printf在linux中大概有哪些语法
命令 作用 解释
printf "%s\n" "Hello world" 输出内容 %s作为占位符,\n作为换行符
printf "\e[1;34m%.3d\e[0m\n" 42 输出一个数字 \e 表示科学计数法;剩余表示字体颜色
printf "\u20AC %.2f\n" 123.4 输出浮点数 现实字符编码 浮点数
printf "var1: %s\tvar2: %s\n" "$VAR1" "$VAR2" 占位输出 可以取变量
printf -v myvar "This is %s = %d\n" "a year" 2016 将内容存储到变量 该操作在zsh上不支持。我就不看我什么了
  • 大概我们将上述常用的四种命令抽象下为
 printf "format" content
复制代码
控制字母 功 能
c 将一个数作为 ASCII 显示
d 显示一个整数值
i 和 d —样,也是显示一个整数值
e 用科学计数法显示一个数
f 显示一个浮点值
g 用科学计数法或浮点数显示(选择较短的格式)
o 显示一个八进制数
s 显示一个文本字符串
x 显示一个十六进制值
X 显示一个十六进制值,但使用大写字母 A~F
% 其实符号,不可缺失
- 有 - 表示左对齐输出,如省略表示右对齐输出
m.n m表示所占宽度。n表示内容精度
l 或 h l就是long ; h就是short
  • printf是按照我们空格匹配的。比如说我们执行下面分别匹配四次
 printf "%s\n" a b c d
复制代码

image-20220601163245050.png

  • 进度条左侧需要从左开始现实我们进度元素,右侧作为动画展示,其中我们可以展示数字化的进度。那么很自然我们可以将进度条内容格式化为以下内容
 printf "%-100s %d%" '#' 1
复制代码

image-20220601164845885.png

  • linux命令这样操作;但是shell脚本里需要稍微改动点
 printf "[%-25s][%d%%][%c]\r"
复制代码

实战

  • 理论知识准备好了之后呢?我们开始实战模拟,我打算制作一个项目启动的进度条。前置条件就是通过ssh 或者sshpass命令远程启动脚本。然后通过进度条取检测服务是否正常启动并运行了。这里我们就不仅仅在进度条里做进度渲染了还得去查询对应的服务端口是否启动了。
  • 这里的进度条只能是一种模拟的进度条,我们只能认为服务正在启动然后检测到端口后就立马到100% 。 这里我们需要预留服务启动的时间。我们按照这个时间去做进度条的加载。
  • 上面已经知道实际是通过printf来完成进度渲染。那么服务端口的检测该怎么来实现呢?这里就需要扯出linux有一大利器awk.关于awk我们油专门章节梳理。下面直接运用
 lsof -i:8080 | awk -F "[ ]+" 'NR>1{print $2}'
复制代码
  • 基于上面的命令我们就能完成进度条了。
 #!/bin/bash
 i=0
 str='#'
 ch=('|' '' '-' '/')
 index=0
 while [ $i -le 25 ]
 do
     printf "[%-25s][%d%%][%c]\r" $str $(($i*4)) ${ch[$index]}
     str+='#'
     let i++
     let index=i%4
     pid=`lsof -i:8080 | awk -F "[ ]+" 'NR>1{print $2}'`
     if [[ -n $pid ]]
     then
         i=25;
         str=#########################
     fi
     sleep 1
 done
 printf "\n"
 echo "安装完成
复制代码
  • 进度条在渲染的过程中会不停的检测8080端口是否启动成功了。成功之后会立马将进度条填满。

\

猜你喜欢

转载自juejin.im/post/7105926333766565896