【问题标题】:How to strip ANSI escape codes from AIX topas command result in C#如何从 C# 中的 AIX topas 命令结果中去除 ANSI 转义码
【发布时间】:2017-09-16 09:47:58
【问题描述】:

我正在尝试使用 C# 控制台应用程序捕获 AIX 实时信息,例如 CPU、内存、IO 负载,因为我想在第三方自定义仪表板中显示这些信息。 运行命令 topas 后,我需要定期捕获以下整个文本:

我尝试使用在某个论坛中找到的以下代码来捕获它:

using Renci.SshNet;
using System;
using System.IO;
using System.Threading;

namespace SSH_check_commands
{
public class MyAsyncInfo
{
    public MyAsyncInfo(Byte[] array, ShellStream stream)
    {
        ByteArray = array;
        Stream = stream;
    }

    public Byte[] ByteArray { get; set; }
    public ShellStream Stream { get; set; }
}

class Program
{
    private static ShellStream stream;
    private static SshClient client;
    private static byte[] _data = new byte[2048];
    static void Main(string[] args)
    {
        client = new SshClient("host", "user", "password");
        client.Connect();
        stream = client.CreateShellStream(@"xterm", 80, 24, 800, 600, 1024);
        stream.DataReceived += StartAsyncRead;
        stream.Write("bash\n");
        Thread.Sleep(5000);
        stream.Write("topas -i 10\n");
        Console.ReadLine();
    }

    private static void StartAsyncRead(object sender, EventArgs e)
    {
        try
        {
            stream.BeginRead(_data, 0, _data.Length, OnReadCompletion, new MyAsyncInfo(_data, stream));

        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }

    private static void OnReadCompletion(IAsyncResult ar)
    {
        try
        {
            var mai = (MyAsyncInfo)ar.AsyncState;
            int datalen = mai.Stream.EndRead(ar);
            string line = client.ConnectionInfo.Encoding.GetString(mai.ByteArray, 0, datalen);
            Console.Write(line);
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }
    public static string SendCommand(string cmd, ShellStream sh)
    {
        StreamReader reader = null;
        try
        {
            reader = new StreamReader(sh);
            StreamWriter writer = new StreamWriter(sh);
            writer.AutoFlush = true;
            writer.WriteLine(cmd);
            while (sh.Length == 0)
            {
                Thread.Sleep(1000);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("exception: " + ex.ToString());
        }
        return reader.ReadToEnd();
    }
}
}

但我无法解析结果,因为它不是结构化的:

你能帮帮我吗?

解决方法

我已经改变了解决问题的方法。 我无法通过 ssh 流捕获整个文本,因为我只收到更改的字符。 因此,我会定期运行以下 ssh 命令将 nmon 内容保存在文件中(称为 hostname_YYMMDD_H24_mm.nmon):

nmon -f -c 1

使用 cat 命令后,我可以读取文件、提取内容、对其进行转换并将其加载到我的仪表板中。

【问题讨论】:

  • 这不是解决方法,这是正确的解决方案!正如我半年前建议的那样。

标签: c# .net shell ssh ssh.net


【解决方案1】:

结果是结构化的。那些是ANSI escape codes。您可以解析这些,就像您的 SSH 终端客户端解析这些以显示漂亮的输出一样。

但这是一项艰巨的任务。见SSH.NET based colored terminal emulator


虽然我会说,首先尝试解析供人类使用的命令的输出是一个坏主意。当然,还有另一种方法可以以更易于解析的格式检索相同的信息。但这是另一个网站的问题(例如Super User)。


如果只想去掉ANSI转义码,可以使用正则表达式,如How to remove ^[, and all of the escape sequences in a file using linux shell scripting所示:

s = new Regex(@"\x1B\[[^@-~]*[@-~]").Replace(s, "");

【讨论】:

    猜你喜欢
    • 2021-02-25
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 2021-09-15
    • 2019-07-14
    • 1970-01-01
    相关资源
    最近更新 更多