c - 在 C 中用颜色复制当前路径
问题描述
我正在使用 Linux Ubuntu,我想用着色复制当前的终止路径。本质上,我希望我的程序使用用户终端的颜色来打印\u@\h:\w$
这篇文章。换句话说,完全复制了(user)@(host):(pwd)$
向下着色的路径。
我遇到的两个问题:
1)我正在尝试使用system("\u@\h:\w$ ")
,但无论我做什么,我都无法逃脱特殊字符。
2) 我找不到用户使用的颜色。
解决方案
这里的问题很少。
解析PS1
环境变量由 shell 完成。Shell(例如 bash)正在将 '\u' 字符串转换为 '(user)'。这不是系统调用。
系统调用执行一个文件名,因此system("\u@\h:\w$ ")
您希望执行一个名为\u@\h:\w$
. 我认为您的系统上没有这样的程序,这不是您的意图。您想打印当前记录的用户名,而不是执行名为“\u”的程序。您想执行名为whoami的程序,它将打印当前用户的用户名。
不知道你要什么颜色。unix shell 中的着色是使用ANSI 转义码完成的. 您只需 printf 一堆字符,您的终端就会为所有后续字符着色。
用 C 程序打印这个精确的输出比这更复杂,无论如何挑战等待着。以下程序将打印(user)@(host):(pwd)$
. 部分(user)@
为红色,部分(host):
为黄色,部分(pwd)$
为洋红色。我正在使用popen posix 调用来执行一个进程并获取它的输出。
#define _GNU_SOURCE
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_BLUE "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN "\x1b[36m"
#define ANSI_COLOR_RESET "\x1b[0m"
void exec_and_grab_output(const char cmd[], char *outbuf, size_t outbuflen) {
size_t outbufpos = 0;
FILE *fp;
char tmpbuf[100];
/* Open the command for reading. */
fp = popen(cmd, "r");
assert(fp != NULL);
/* Read the output a line at a time - output it. */
while (fgets(tmpbuf, sizeof(tmpbuf)-1, fp) != NULL) {
assert(outbufpos <= outbuflen);
const size_t tmpbufpos = strlen(tmpbuf);
memcpy(&outbuf[outbufpos], tmpbuf, tmpbufpos);
outbufpos += tmpbufpos;
}
/* close */
pclose(fp);
}
int main()
{
char outbuf[2048];
exec_and_grab_output("whoami", outbuf, sizeof(outbuf));
printf(ANSI_COLOR_RED);
assert(strlen(outbuf) > 2);
outbuf[strlen(outbuf)-2] = '\0'; // remove newline from output
printf("%s@", outbuf); // this will be red
exec_and_grab_output("hostname", outbuf, sizeof(outbuf));
printf(ANSI_COLOR_YELLOW);
assert(strlen(outbuf) > 2);
outbuf[strlen(outbuf)-2] = '\0'; // remove newline from output
printf("%s:", outbuf); // this will be yellow
exec_and_grab_output("pwd", outbuf, sizeof(outbuf));
printf(ANSI_COLOR_MAGENTA);
assert(strlen(outbuf) > 2);
outbuf[strlen(outbuf)-2] = '\0'; // remove newline from output
printf("%s$", outbuf); // this will be in magenta
printf(ANSI_COLOR_RESET);
return 0;
}
如果你想在 shell 中着色 PS1 变量的输出(不是 C,C 是一种编程语言,shell 是一个程序),你可以在你的 bash 终端中输入:
export PS1="\033[31m\u@\033[33m\h:\033[36m\w$\033[0m"
该部分与上面 C 程序中\033[31m
的部分 1:1 对应。"\x1b[31m"
Bash 会将\033[31m
字符打印到终端(当打印 PS1 时),然后终端会将所有后续字符着色为红色。Bash 将扩展\u
为当前用户的名称。等等。
推荐阅读
- python - 在滚动菜单中全选后抓取
- python - 尝试训练 keras 模型时,出现错误:没有为任何变量提供梯度
- nginx - 如何通过服务器ip地址限制对prometheus的直接IP访问?
- elasticsearch - Filebeat 到 Elasticsearch:document_id 被移除(用于自定义 _id 时)
- asp.net-mvc - 是否可以将多个内容类型路由和绑定到同一个操作?
- angular - Angular Elements - 多个实例默认共享同一个服务
- cmake - cmake链接库与内部依赖
- import - 在keras中导入乘法LSTM的麻烦
- python - 在子进程中产生的补丁对象
- python - 使用python/xarray,如何将每月时间序列(向量)重塑为行为月、列为年的矩阵?