正在解析 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 来帮助我:
- 查看第 090 行显示字母
ive: fa
的第二批 8 个字符,我发现:
- 69=我
- 76 = v
- 65 = e
- 3a = :
- 20 = space
- 66 = f
- 61=一个
- 69=我
控制序列没有字节。
我想知道 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=always
、grep --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
我正在尝试在 HTML 中呈现 linux shell 命令的输出。例如,systemctl status mysql
在我的终端中看起来像这样:
正如我从 Floz'z Misc 了解到的那样,我期望底层字符流包含控制代码。但是看着它说 hexyl
(systemctl status mysql | hexyl
) 我看不到任何代码:
查看显示文本“Active: failed”的第 080 行和 090 行的底部附近,我希望找到一些控制序列来将颜色更改为红色。虽然不一定是 ascii,但我使用了一些 ascii tables 来帮助我:
- 查看第 090 行显示字母
ive: fa
的第二批 8 个字符,我发现: - 69=我
- 76 = v
- 65 = e
- 3a = :
- 20 = space
- 66 = f
- 61=一个
- 69=我
控制序列没有字节。
我想知道 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=always
、grep --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