如何实现一个命令行的进度条

时间:2021-1-8 作者:admin

如何实现一个命令行的进度条

很多CLI工具为了提高DX,在做耗时长的工作时,都会在命令行显示一个进度条。web端的进度条写多了,命令行的进度条还没写过,所以这里造个简易轮子,了解下原理。

任务分解

分解下任务,要实现一个进度条,要做到以下工作

  1. 传入一个进度数值X,绘制100%的进度容器和X%的进度条部分部分

这个实现简单,只需要 X% 部分和(100-X)%部分的字符不同即可。

  1. 每次进度变化,清除当前已绘制部分,绘制更新后的进度内容

在浏览器端实现这点很容易,清除绘制部分都由渲染进程处理,在命令行终端可以用 ANSI 转义序列控制字符绘制,具体可以参考 维基百科

简单来说,ANSI 就是控制终端输出的色彩、样式、光标位置以及控制终端行为的特殊字节. 一个ANSI转义字符通常以 \x1b[ 开头,\x1b[ 也叫做 CSI (Control Sequence Introducer), CSI
后面跟不同的编码可以表示不同的字符格式。

ANSI

For Many Examples,

  • 显示红字

    echo '\x1b[31;m hello world!'
    

  • 光标移动,清除整行

    echo "hello world \x1b[2K"
    

  • 来一手五彩斑斓的A

    ![](/public/upload/400c9881950f5b0c7778c41b9f1300d1.png)
    

其它具体的转义码参考 维基百科,现在画笔画板都有了,图怎么画就看画家的手了。

简易进度条

有了以上的前置知识,写了简单的进度条就简单了

const prefix = '[';
const postfix = ']';
const MAX_CHARS = 40;

function render(precent: number) {
  const arrowNumber = ~~(MAX_CHARS * precent);
  const bar = '>'.repeat(arrowNumber) + ' '.repeat(MAX_CHARS - arrowNumber);
  const curProcessbar = `\x1b[1A\x1b[2K${prefix}${bar}${postfix} ${Math.floor(
    precent * 100
  )}%`;
  console.log(curProcessbar);
}

let cur = 0;
const timer = setInterval(() => {
  if (cur >= 100) {
    clearInterval(timer);
    return;
  }
  cur++;
  render(cur / 100);
}, 16);

如何实现一个命令行的进度条

给你点 color 看看

const MAX_CHARS = 40;

function render(precent: number) {
  const arrowNumber = ~~(MAX_CHARS * precent);
  const bar =
    '\x1b[31m' +
    '▓'.repeat(arrowNumber) +
    '\x1b[34m' +
    '░'.repeat(MAX_CHARS - arrowNumber);
  const curProcessbar = `\x1b[1A\x1b[2K${bar} ${Math.floor(precent * 100)}%`;
  console.log(curProcessbar);
}

let cur = 0;
const timer = setInterval(() => {
  if (cur >= 100) {
    clearInterval(timer);
    return;
  }
  cur++;
  render(cur / 100);
}, 16);

如何实现一个命令行的进度条

总结

ANSI转义序列(ANSI escape sequences)是一种带内信号的转义序列标准,用于控制视频文本终端上的光标位置、颜色和其他选项。在文本中嵌入确定的字节序列,大部分以ESC转义字符和”[“字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的字符编码。

命令行也是终端一种,对用户可视的都是前端范畴,学会了ANSI也可以命令行内写画骚操作。

github地址

参考

ANSI 转义序列

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。