首页 > 解决方案 > 清除 Linux 终端仿真器中的最后两个(及更多)打印行

问题描述

我曾经看到一个控制台应用程序,它使用多个进度条可视化多个下载的进度,每个进度条都在自己的行上。我很好奇如何做到这一点,但我只找到了部分解决方案。他们来了:

一个进度条很简单

很容易用“回车”清除一行,从而可视化一个进度条,正如在这个问题中所讨论的那样。易于使用,也有很多帮助库。

“使用 ncurses”

每个人都说“使用 ncurses”。但据我所知,每个 ncurses 程序都必须以initscr()call 开头,这确实清除了整个屏幕。您的提示消失了,您的终端历史记录消失了。这不是我想要的。

使用 ncurses 中的 terminfo

使用sc,edrc能力terminfo, 说明这个 Bash 脚本(脚本取自这个问题):

tput sc; while [ true ]; do tput ed; echo -e "$SECONDS\n$SECONDS\n$SECONDS"; sleep 1; tput rc; done

这有效,但仅在xterm. 我的urxvt术语忽略它,与 eg 相同terminator

那么还有哪些其他选择呢?

标签: linuxterminalconsole-application

解决方案


正如用户@Marged 正确指出的那样,ANSI 转义序列就是答案。

这是适用于我的 C 代码。关键是第 19 行,它打印擦除最后两行的 ANSI 序列(行数是任意的,在序列中说明):

#include <stdio.h>
#include <unistd.h>

void progressBar(int done, int total) {
    int i;
    printf("[");
    for (i=0; i<total; ++i) {
        printf((done < i) ? " " : "=");
    }
    printf("]\n");
}

int main() {
    int i;
    for (i=0; i<5; ++i) {
        progressBar(i, 4);
        progressBar(2*i, 8);
        if (i != 4) {
            printf("\033[2A");  // This erases last two lines!
            sleep(1);
        }
    }
    return 0;
}

推荐阅读