【问题标题】:Reading and processing command output line by line in SSH.NET在 SSH.NET 中逐行读取和处理命令输出
【发布时间】:2019-12-18 13:07:52
【问题描述】:

我正在做一个家庭项目,该项目需要通过 SSH 执行一些命令,读回响应并将它们显示在网页上。很多时候它确实有效,但有时我会遇到一些不一致的行为,例如缺少某些输出行,这些行会指示下一步该做什么,这会导致会话挂起,并且需要恢复 IIS。

我已经包含了下面的代码,就像我说我不是全职开发人员一样,所以它会一团糟,但希望有人能指出我正确的方向,以了解我做错了什么,以及我需要什么要改变,我不会知道你是否只是通过代码 sn-ps,我宁愿尝试尝试修复我所拥有的。

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

我认为我错了
我认为由于我读取控制台输出的方式而出现这些错误。我认为数据变化如此之快,以至于我们错过了一些:

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

因此,使用对输出的 3 个检查中的每一个,我认为可能会丢失一些行,因为输出非常快,而它读取的值会发生变化,因此下一个检查有不同的初始化数据要检查,并且因此我们跳过了退出线或下一个工作线。

【问题讨论】:

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


    【解决方案1】:

    您必须将读取的行存储到变量中,并根据存储的值进行检查:

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

    【讨论】:

    • 接受了这个作为我使用的答案:) - 一行和一些修改所产生的差异令人难以置信。我以为我以前很偏执,因为我通常希望看到的输出丢失了,现在它是返回数据的完美副本,现在每次都会触发触发器,我用 var 代替字符串。实际上很惊讶那有多大的差异,我会继续测试它,但现在是 5 比 5 :) 再次感谢马丁
    猜你喜欢
    • 2020-03-12
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 2015-10-13
    相关资源
    最近更新 更多