terminal程序颜色打印疑问

为什么通过shell调用grep, grep显示的就没有没有颜色? 加上了color=always就有了?

Gpt回答(简化)

当你在终端中直接使用 grep 命令时,grep 默认会根据终端的能力来决定是否显示带颜色的输出。如果它检测到输出被重定向(比如重定向到文件或者通过管道传递给另一个命令),就会认为终端不支持颜色,因此默认情况下不输出带颜色的结果。

--color=autogrep 的默认设置

例子

grep --color=auto "pattern" file.txt | less
grep --color=always "pattern" file.txt | less

原来,一个程序信息打印,颜色显示是可以控制的。以前遇到一个问题,写了一个有颜色标准输出的程序,其他人把程序用重定向,把标准输出显示在UI上的时候,因为有颜色的格式导致文本看起来很乱。当时为了规避,就把颜色打印去掉了。现在可以参考一下这个,在写代码对于输出做一个颜色控制

1. grep是如何通过一个变量控制--color=always的?(gpt)

void output_match(const char *line, const char *match_start, const char *match_end) {
    if (use_color()) {
        printf("\033[01;31m");  // Start color (red)
        fwrite(line, 1, match_start - line, stdout);
        printf("\033[m");  // End color
        fwrite(match_start, 1, match_end - match_start, stdout);
        printf("\033[01;31m");  // Start color (red)
        fwrite(match_end, 1, strlen(match_end), stdout);
        printf("\033[m");  // End color
    } else {
        fwrite(line, 1, strlen(line), stdout);
    }
}

2. less命令是什么?拿来干嘛的?

less与cat类似,用来在终端查看文件的。

Cat file.txt 将会打印信息在终端上,如果file.txt内容太多,显示在终端后,导致终端容易乱。

less提供了文本浏览器的角色,less打开一个文本后,查看、搜索文本,退出后,终端没有多余的信息。

在这里插入图片描述

2.1 less这种打印的模式是怎么设计的?基于什么原理?(按q后,恢复原始终端信息)

相比于cat是直接输出到terminal。可以利用在自己平时写程序里的help模块,防止显示太多信息太乱。

经过几次提问,才搞出来,当然图省事,直接看源码就行了。这个程序可以运行,基本实现我要的功能,显示文件的一部分,按q后退出,恢复终端。

逻辑是保护和恢复现场

跟进程上下文切换类似,保护堆栈等信息。

    enable_raw_mode();
    save_cursor_position();
    save_screen();
    clear_screen();
    display_page(file);
    restore_screen();
    restore_cursor_position();
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define BUFFER_SIZE 4096
#define PAGE_LINES 24  // Number of lines per page

struct termios orig_termios;

void disable_raw_mode() {
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
}

void enable_raw_mode() {
    tcgetattr(STDIN_FILENO, &orig_termios);
    atexit(disable_raw_mode);

    struct termios raw = orig_termios;
    raw.c_lflag &= ~(ECHO | ICANON | ISIG);
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}

void clear_screen() {
    printf("\033[2J");
    printf("\033[H");
}

void save_cursor_position() {
    printf("\0337");  // Save cursor position
}

void restore_cursor_position() {
    printf("\0338");  // Restore cursor position
}

void save_screen() {
    printf("\033[?1049h");  // Save screen
}

void restore_screen() {
    printf("\033[?1049l");  // Restore screen
}

void display_page(FILE *file) {
    char buffer[BUFFER_SIZE];
    int lines_displayed = 0;
    size_t bytes_read;

    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0) {
        for (size_t i = 0; i < bytes_read; i++) {
            putchar(buffer[i]);
            if (buffer[i] == '\n') {
                lines_displayed++;
                if (lines_displayed >= PAGE_LINES) {
                    // Wait for user input to continue
                    char c;
                    read(STDIN_FILENO, &c, 1);
                    if (c == 'q') {
                        return;
                    }
                    clear_screen();
                    lines_displayed = 0;
                }
            }
        }
    }
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    FILE *file = fopen(argv[1], "r");
    if (!file) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    enable_raw_mode();
    save_cursor_position();
    save_screen();
    clear_screen();
    display_page(file);
    restore_screen();
    restore_cursor_position();

    fclose(file);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值