正在解析 linux 个颜色控制序列

Parsing linux color control sequences

我正在尝试在 HTML 中呈现 linux shell 命令的输出。例如,systemctl status mysql 在我的终端中看起来像这样:

正如我从 Floz'z Misc 了解到的那样,我期望底层字符流包含控制代码。但是看着它说 hexyl (systemctl status mysql | hexyl) 我看不到任何代码:

查看显示文本“Active: failed”的第 080 行和 090 行的底部附近,我希望找到一些控制序列来将颜色更改为红色。虽然不一定是 ascii,但我使用了一些 ascii tables 来帮助我:

控制序列没有字节。

我想知道 hexyl 是否选择不显示它们,所以我写了一个 Java 程序,在作为 bash 脚本执行该过程后输出原始字节,结果是相同的 - 不控制序列。

Java大致是:

p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "systemctl status mysql"}); // runs in the shell
p.waitFor();
byte[] bytes = p.getInputStream().readAllBytes();
for(byte b : bytes) {
    System.out.println(b + "\t" + ((char)b));
}

输出:

...
32   
32   
32   
32   
32   
65  A
99  c
116 t
105 i
118 v
101 e
58  :
32   
102 f
97  a
105 i
108 l
101 e
100 d
...

所以问题是:bash怎么知道它必须显示红色的“失败”字样?

systemctl 检测到 输出不是终端,它会从输出中删除颜色代码。

相关:Detect if stdin is a terminal or pipe? , https://unix.stackexchange.com/questions/249723/how-to-trick-a-command-into-thinking-its-output-is-going-to-a-terminal , https://superuser.com/questions/1042175/how-do-i-get-systemctl-to-print-in-color-when-being-interacted-with-from-a-non-t

工具有时(有时不)带有始终启用颜色代码的选项,例如 ls --color=alwaysgrep --color=always 在具有 SYSTEMD_COLORS 环境变量的 systemd 的情况下。


What tool can I use to see them?

您可以使用 hexyl 查看它们。

how does bash know that it has to mark the word "failed" red?

Bash就是shell,完全没有关系。

您的终端,您正在查看输出的图形window,知道将其标记为红色,因为输出中的 ANSI 转义序列。与 Bash.

没有互动
$ SYSTEMD_COLORS=1 systemctl status dbus.service | grep runn | hexdump -C
00000000  20 20 20 20 20 41 63 74  69 76 65 3a 20 1b 5b 30  |     Active: .[0|
00000010  3b 31 3b 33 32 6d 61 63  74 69 76 65 20 28 72 75  |;1;32mactive (ru|
00000020  6e 6e 69 6e 67 29 1b 5b  30 6d 20 73 69 6e 63 65  |nning).[0m since|
00000030  20 53 61 74 20 32 30 32  32 2d 30 31 2d 30 38 20  | Sat 2022-01-08 |
00000040  31 39 3a 35 37 3a 32 35  20 43 45 54 3b 20 35 20  |19:57:25 CET; 5 |
00000050  64 61 79 73 20 61 67 6f  0a                       |days ago.|
00000059