SSH.NET не обрабатывает мои команды ввода оболочки

Я использую SSH.NET для подключения к моему Raspberry Pi из консольного приложения на С#.

Я хочу отправить текст из моего собственного потока, написав в него через StreamWriter.

Проблема в том, что он ничего не делает. Как будто WriteLine("ls") не дает никакого эффекта.

Это код:

using System;
using System.IO;
using Renci.SshNet;

namespace SSHTest
{
    class Program
    {
        static void Main(string[] args)
        {

            var ssh = new SshClient("raspberrypi", 22, "pi", "raspberry");
            ssh.Connect();

            var input = new MemoryStream();
            var streamWriter = new StreamWriter(input) { AutoFlush = true };

            var shell =
                ssh.CreateShell(input, Console.OpenStandardOutput(), new MemoryStream());
            shell.Start();

            streamWriter.WriteLine("ls");

            while (true)
            {               
            }
        }
    }
}

В чем проблема?

Спасибо заранее :)


person SuperJMN    schedule 13.06.2017    source источник


Ответы (1)


MemoryStream не является хорошим классом для реализации входного потока.

Когда вы записываете в MemoryStream, как и в большинстве реализаций потоков, его указатель перемещается в конец записываемых данных.

Поэтому, когда канал SSH.NET пытается прочитать данные, ему нечего читать.

Вы можете переместить указатель назад:

streamWriter.WriteLine("ls");
input.Position = 0;

Но правильный подход — использовать PipeStream из SSH.NET, который имеет отдельные указатели чтения и записи (так же, как * nix pipe):

var input = new PipeStream();

Другой вариант — использовать SshClient.CreateShellStream (класс ShellStream), который предназначен для такой задачи. Он дает вам один Stream интерфейс, который вы можете писать и читать.

См. также Возможно ли выполнение нескольких команд SSH из одного сеанса входа с помощью SSH.NET?


Хотя SshClient.CreateShell (канал оболочки SSH) не является правильным методом для автоматизации выполнения команд. Используйте исполнительный канал. Для простых случаев используйте SshClient.RunCommand. Если вы хотите постоянно читать вывод команды, используйте SshClient.CreateCommand для получения потока вывода команды:

var command = ssh.CreateCommand("ls");
var asyncExecute = command.BeginExecute();
command.OutputStream.CopyTo(Console.OpenStandardOutput());
command.EndExecute(asyncExecute);
person Martin Prikryl    schedule 14.06.2017
comment
Большое спасибо! Это сработало, теперь, когда это работает, я хотел бы пойти дальше. Это еще один вопрос: stackoverflow.com/questions /44549443/ - person SuperJMN; 14.06.2017
comment
Кстати, весь код находится в сети и с открытым исходным кодом. Это здесь, если вы хотите взглянуть! github.com/SuperJMN/UniversalSSH - person SuperJMN; 14.06.2017