使用SSH.net在命令输出期间发送输入

时间:2017-11-13 11:49:35

标签: c# ssh putty plink ssh.net

使用PuTTY,我连接到SSH服务器然后执行一个不断输出日志的命令(每秒多行)。在这个过程中,我可以发送一些命令,即。放置123 Esc 会停止进程。如果我输入有效的击键,我可以在输出设备上看到它,所以我总是知道是否发送了击键。

我想以编程方式执行此操作 - 连接到SSH服务器,执行main命令,然后将其作为命令发送一些按键,同时监视日志,我可以看到对命令的响应。

所以我想用SSH.NET做它 - 它是一个简洁的SSH工具,它可靠地输出,并且它很好用。但是我有一个问题 - 我可以连接到这个服务器,执行命令,但是当它转储日志时我无法发送任何键击。

我尝试使用CreateShellStream

的方法
  • shellStream.WriteLine('keystroke in ascii or just string')
  • sshClient.CreateCommand('keystroke in ascii or just string')然后sshClient.Execute();
  • 使用StreamWriter(shellstream)并写信给

我尝试过ascii代码,UTF-16代码,字符串,遗憾的是没有任何作品。

使用Plink(PuTTY命令行工具)完成同样的工作很好,但它更麻烦,我更喜欢使用SSH.NET。你知道用SSH.NET和Plink发送击键有什么区别吗?为什么它与Plink完美配合?我已经尝试过用Wireshark调试它,不幸的是SSH使得它很难这样做。

Plink我基本上使用了这样的东西:

ProcessStartInfo psi = new ProcessStartInfo("plink.exe", arguments);
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
plink = Process.Start(psi);
StreamWriter input = plink.StandardInput;
StreamReader output = plink.StandardOutput;

input.WriteLine("startCommand"); //Starts the process responsible for logs

input.Write("950"); //It correctly sends the keystrokes

// Some code regarding reading logs from output, some other commands sent to ssh server...

Console.WriteLine("Exiting...");
input.Write('\u001b');  //ESC in UTF16

我认为SSH.NET在发送任何其他命令之前等待最后一个命令结束,但我不知道如何更改它。

我尝试使用SSH.NET:

using (var client = new SshClient(host, user, new PrivateKeyFile(key)))
{
    int timoutCounter = 0;
    do
    {
        timoutCounter++;
        try { client.Connect(); }
        catch (Exception e)
        {
            Console.WriteLine("Connection error: " + e.Message);
        }
    } while (!client.IsConnected);

    ShellStream stream = client.CreateShellStream("shell", 200, 24, 1920, 1080, 4096);

    // it starts the process on remote ssh server that 
    stream.WriteLine("startCommand"); 
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    for (int i = 0; i < 30; i++)
    {
        // Just some quick way for me to know that the device fully loaded
        stream.Expect("LogKeyWord");
    }
    Console.WriteLine("Device started");
    Console.ReadKey();

    // Different ways of entering commands during log output that I've tried

    stream.Write("5"); 
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    stream.WriteLine("6");
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    stream.Write("\u001b"); 
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    var test97 = new StreamWriter(stream);
    test97.Write("7");
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    test97.WriteLine("8");
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    client.RunCommand("11");
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    var test = client.CreateCommand("31");
    test.Execute();
    Console.Write("Waiting for any key...");
    Console.ReadKey();

    client.Disconnect();
}

1 个答案:

答案 0 :(得分:1)

只是猜测,但我会尝试刷新流。

更新:

写了一个小实验,我无法重现该问题。看看这里:https://github.com/scottstephens-repros/SSHNetInterleavedIORepro

所以这可能是特定于您的代码、您尝试远程运行的程序或远程机器的操作系统、sshd 或配置的问题。我的远程测试机是 CentOS 7.8,OpenSSH 7.4p1。