2

I am working on a home project that needs to execute some commands via SSH, read back the responses and display them on a web page. A lot of the time it does work, but now and then i get some inconsistent behavior, for example certain lines of output are missed that would instruct on what to do next, this results in a hung session, and a requirement to restore IIS.

I have included the code below, like I said I am not a full time developer, so its gonna be a mess, but hopefully someone can point me in the right direction to understand what i got so wrong, and what i need to change, i wont learn if you just past code snippets up, id much rather attempt to try and fix what i have.

using (SshClient ssh = new SshClient("192.168.0.119", "x", "x."))
{
    ssh.Connect();
    ShellStream shell = ssh.CreateShellStream("Tail", 0, 0, 0, 0, 1024);
    StreamWriter wr = new StreamWriter(shell);
    StreamReader rd = new StreamReader(shell);
    wr.AutoFlush = true;
    if (extract)
    {
        Console.WriteLine("Downloading DataZIP");
        ssh.RunCommand("wget " + zipURL);
    }

    bool reading = shell.CanRead;
    wr.WriteLine("cd " + remoteFilePath + packagename + " && docker build -t dockerfile .");

    while (reading)
    {
        Clients.Caller.builderOut(shell.ReadLine().ToString());
        if (shell.ReadLine().ToString().Contains("Successfully"))
        {
            Clients.Caller.builderOut("Build Complete");
            reading = false;
        }
        if (shell.ReadLine().ToString().Contains("returned a non-zero code: "))
        {
            goto end;
        }
    }

    if (data.Type == TemplateType.Data)
    {
        wr.WriteLine("cd " + remoteFilePath + packagename + " && docker tag dockerfile " + data.Repository + "/" + data.packagename.ToLower() + ":data.Type");
        wr.WriteLine("cd " + remoteFilePath + packagename + " && docker push " + data.Repository + "/" + data.packagename.ToLower() + ":data.Type");
    }

    reading = shell.CanRead;
    while (reading)
    {
        Clients.Caller.builderOut("Pushing this will take a moment");
        if (shell.ReadLine().ToString().Contains("digest:"))
        {
            Clients.Caller.builderOut("Pushed");
            reading = false;
        }
    }

    Clients.Caller.builderOut("End");
    ssh.Disconnect();
    ssh.Dispose();
}

What I think I got wrong
I think I get these errors due to the way I'm reading the console output. I think that that data changes so fast we miss some:

while (reading)
{
    Clients.Caller.builderOut(shell.ReadLine().ToString());
    if (shell.ReadLine().ToString().Contains("Successfully"))
    {
        Clients.Caller.builderOut("Build Complete");
        reading = false;
    }
    if (shell.ReadLine().ToString().Contains("returned a non-zero code: "))
    {
        goto end;
    }
}

So using that each of the 3 checks on the output could I think be be missing some of the lines, as the output is quite speedy, while its reading the value changes so the next check has different init data to check, and thus we skip over what would otherwise be the exit lines or next job lines.

1 Answer 1

2

You have to store the line that you read into a variable and do the checks against the stored value:

while (reading)
{
    string line = shell.ReadLine();
    Clients.Caller.builderOut(line);
    if (line.Contains("Successfully"))
    {
        Clients.Caller.builderOut("Build Complete");
        reading = false;
    }
    if (line.Contains("returned a non-zero code: "))
    {
        goto end;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Accepted this as the answer for my usage :) - The difference that one line and a few modifications have made are incredible. I thought i had been paranoid before because output i would normally expect to see was missing, now its a perfect copy of the data being returned, triggers are hit now every time, i went with var over string. Actually amazed how much diffrence thats made, ill keep testing it but thats 5 for 5 now :) Once again thank you Martin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.