How to strip ANSI escape codes from AIX topas command result in C#

1.5k Views Asked by At

I'm trying to capture AIX real-time information like CPU, memory, IO load with a C# console application because I would like to show that information in a third part custom dashboard. After running the command topas, I need to capture periodically the whole following text:

enter image description here

I tried to capture it with the following code that I have found out in some forum:

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();
    }
}
}

But I can't parse the result because it's not structured:

enter image description here

Could you please help me?

Workaround:

I have changed the approach to the problem. I could not catch whole text with ssh streaming because I receive only changed chars. Hence periodically I run the following ssh command to save nmon content in a file (called hostname_YYMMDD_H24_mm.nmon):

nmon -f -c 1

After with the cat command I can read the file, extract the content, transform it and load it in my dashboard.

1

There are 1 best solutions below

0
On

The results are structured. Those are ANSI escape codes. You can parse those, the same way your SSH terminal client parses those to display the nice output.

But that's a huge task. See SSH.NET based colored terminal emulator.


Though I'd say that trying to parse an output of a command that is intended for a human use is a bad idea, in the first place. For sure there's another way to retrieve the same information in a format that's easier to parse. But that's a question for another site (for example Super User).


If you just want to strip the ANSI escape codes, you can use a regular expression, as shown in How to remove ^[, and all of the escape sequences in a file using linux shell scripting:

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