为什么通过shell调用grep, grep显示的就没有没有颜色? 加上了color=always就有了?
Gpt回答(简化)
当你在终端中直接使用
grep
命令时,grep
默认会根据终端的能力来决定是否显示带颜色的输出。如果它检测到输出被重定向(比如重定向到文件或者通过管道传递给另一个命令),就会认为终端不支持颜色,因此默认情况下不输出带颜色的结果。
--color=auto
是grep
的默认设置例子
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;
}