从C#SSH.NET的ShellStream获取完整的命令输出

时间:2015-12-10 14:40:35

标签: c# ssh ssh.net

使用Renci.SshNet库。我正在尝试执行一些命令。 执行“命令1”后,我正在执行“命令2”,这需要更多的时间。

我只获得输出的第一行。 (reader.ReadToEnd()无法正常工作)。

我也试过while (!reader.EndOfStream){ }而没有运气。

我认为这是因为服务器响应的延迟。当没有响应时,流不读任何内容并完成。

我找到了解决方案

String tmp;
TimeSpan timeout = new TimeSpan(0, 0, 3);
while ((tmp = s.ReadLine()) != null)
{
    Console.WriteLine(tmp);
}

但这不专业。我需要一些方法,当它结束时流结束。

using (var vclient = new SshClient("host", "username", "password"))
{
    vclient.Connect();
    using (ShellStream shell = vclient.CreateShellStream("dumb", 80, 24, 800, 600, 1024))
    {
        Console.WriteLine(SendCommand("comand 1", shell));
        Console.WriteLine(SendCommand("comand 2", shell));
        shell.Close();
    }
    vclient.Disconnect();
}

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(500);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("exception: " + ex.ToString());
    }
    return reader.ReadToEnd();
}               

1 个答案:

答案 0 :(得分:4)

贝壳是一个层出不穷的流。没有发送命令 - 接收输出序列。 ReadToEnd无法知道一个命令的输出结束的位置。你所能做的只是阅读,直到你自己可以告诉输出结束。 如果你不能说出来,你可以通过附加某种输出结束标记来帮助自己:

command 1 ; echo this-is-the-end-of-the-output

并阅读,直至获得"this-is-the-end-of-the-output"行。

通常,“shell”通道不是自动化的理想解决方案。它适用于交互式会话。

您最好使用SshClient.CreateCommand使用“exec”频道。使用CreateCommand,一旦命令完成,通道就会关闭。所以有明确的“流的结尾”,是什么使ReadToEnd()按预期工作。 SSH.NET甚至可以在SshCommand.Result(内部使用ReadToEnd())中提供整个命令输出。