解决ansible输出的结果的颜色字符在前端显示为乱码的问题

问题

当我们在后端保存的ansible输出结果,希望在前端展示的时候,发现颜色部分的字符会显示成乱码的形式

而在后端保存的数据

\nPLAY [测试主 ****************************************************************\n\nTASK [ping主机] ****************************************************************\n\x1b[0;32mok: [10.0.0.200]\x1b[0m\n\nTASK [获取主机***********************************************************\n\x1b[0;33mchanged: [10.0.0.200]\x1b[0m\n\nTASK [打印主机名] **************************************************************\n\x1b[0;32mok: [10200] => {\x1b[0m\n\x1b[0;32m    "hostname.stdout": "dev\\r\\n"\x1b[0m\n\x1b[0;32m}\x1b[0m\n\nPLAY RECAP *********************************************************************\n\x1b[0;33m10.0.0.200\x1b[0m                 : \x1b[0;32mok=3   \x1b[0m \x1b[0;33mchanged=1   \x1b[0m unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \n

那么要如何解决这个问题呢

解决方法

去掉这些颜色字符

在后端利用这则表达式,去掉这些颜色字符

from ansible_runner import run
import re

res = run(
        private_data_dir=workdir,
        playbook=playbook,
        quiet=True,
        rotate_artifacts=1
)
output = re.compile(r'\x1b\[\[?(?:\d{1,2}(?:;\d{0,2})*)?[m|K]').sub('', res.stdout.read())

通过正则表达式 r'\x1b\[\[?(?:\d{1,2}(?:;\d{0,2})*)?[m|K]',去掉那些颜色字符

当然,这样确实能够解决这个乱码的问题

但是,怎么才能保留这些颜色,并且展示呢

前端利用 ansi_up 库

这里简单介绍一个 javascript 库, ansi_up

这个库可将带有 ANSI 终端代码的文本转换为彩色 HTML。

仓库

https://github.com/drudru/ansi_up

简介

ansi_up 是一个易于使用的库,它将包含 ANSI 颜色转义代码的文本转换为 HTML。

该模块是一个单个的 ES6 JavaScript 文件,没有任何依赖关系。

它是 "isomorphic" JavaScript,这只是另一种说法,即 ansi_up.js 文件可以在浏览器或 node.js 中工作。

这个 JavaScript 库是从 TypeScript 编译而来的,其类型描述与 NPM 一起提供。

自 2011 年以来,这段代码一直在生产环境中使用,并且正在积极维护中。

效果

终端的输出字符

ESC[1;Foreground
�[1;30m 30[1;30m 30[1;30m 30[1;30m 30[1;30m 30[1;30m 30[1;30m 30[1;30m 30[0m
�[1;31m 31[1;31m 31[1;31m 31[1;31m 31[1;31m 31[1;31m 31[1;31m 31[1;31m 31[0m
�[1;32m 32[1;32m 32[1;32m 32[1;32m 32[1;32m 32[1;32m 32[1;32m 32[1;32m 32[0m
...

转化后的结果

安装

$ npm install ansi_up

使用示例

浏览器中

<script type="module" type="text/javascript">
var txt  = "\n\n\033[1;33;40m 33;40  \033[1;33;41m 33;41  \033[1;33;42m 33;42  \033[1;33;43m 33;43  \033[1;33;44m 33;44  \033[1;33;45m 33;45  \033[1;33;46m 33;46  \033[1m\033[0\n\n\033[1;33;42m >> Tests OK\n\n"
import { AnsiUp } from './ansi_up.js'
var ansi_up = new AnsiUp();
var html = ansi_up.ansi_to_html(txt);
var cdiv = document.getElementById("console");
cdiv.innerHTML = html;
</script>

javascript

import { AnsiUp } from './ansi_up.js'

const ansi_up = new AnsiUp();
const txt  = "\n\n\x1B[1;33;40m 33;40  \x1B[1;33;41m 33;41  \x1B[1;33;42m 33;42  \x1B[1;33;43m 33;43  \x1B[1;33;44m 33;44  \x1B[1;33;45m 33;45  \x1B[1;33;46m 33;46  \x1B[1m\x1B[0\n\n\x1B[1;33;42m >> Tests OK\n\n"
let html = ansi_up.ansi_to_html(txt);

在react的组件中使用

import { AnsiUp } from "ansi_up/ansi_up";

const APP = () ={
    const current = useRef<DataJobType>();
    // 获取数据的方法
    ......


    return (
        <>
               <div
                style={{
                    whiteSpace: "pre-wrap",
                    backgroundColor: "#333",
                    color: "#fff",
                    borderRadius: "10px",
                    padding: "10px",
                }}
                dangerouslySetInnerHTML={{
                    __html: ansiup.ansi_to_html(current.current),
                }}
            ></div>
        </>      
    )    
}

效果

python的ansible库--ansible_runner参考之前的博客 https://www.cnblogs.com/guangdelw/p/18061452

posted @   厚礼蝎  阅读(127)  评论(0编辑  收藏  举报
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示