Как запускать команды на SSH-сервере на C #?

Мне нужно выполнить это действие с помощью кода C #:

  1. открыть putty.exe в фоновом режиме (это похоже на окно cmd)
  2. войти на удаленный хост, используя его IP-адрес
  3. введите имя пользователя и пароль
  4. выполнить несколько команд одну за другой.
  5. запустите другую команду, которая получит ответ, сообщающий мне, что команды, которые я выполнял до этого, были выполнены успешно

Итак, я пытаюсь сделать это так:

ProcessStartInfo proc = new ProcessStartInfo() 
{
     FileName = @"C:\putty.exe",
     UseShellExecute = true, //I think I need to use shell execute ?
     RedirectStandardInput = false,
     RedirectStandardOutput = false,
     Arguments = string.Format("-ssh {0}@{1} 22 -pw {2}", userName, hostIP, password)
     ... //How do I send commands to be executed here ?
};
Process.Start(proc);

person Liran Friedman    schedule 17.06.2015    source источник


Ответы (2)


Вы можете попробовать https://sshnet.codeplex.com/. При этом вам вообще не понадобится шпатлевка или окно. Вы тоже можете получить ответы. Это выглядело бы так. нравится.

SshClient sshclient = new SshClient("172.0.0.1", userName, password);    
sshclient.Connect();
SshCommand sc= sshclient .CreateCommand("Your Commands here");
sc.Execute();
string answer = sc.Result;

Изменить: Другой подход - использовать shellstream.

Создайте ShellStream один раз, например:

ShellStream stream = sshclient.CreateShellStream("customCommand", 80, 24, 800, 600, 1024);

Затем вы можете использовать такую ​​команду:

  public StringBuilder sendCommand(string customCMD)
    {
        StringBuilder answer;

        var reader = new StreamReader(stream);
        var writer = new StreamWriter(stream);
        writer.AutoFlush = true; 
        WriteStream(customCMD, writer, stream);
        answer = ReadStream(reader);
        return answer;
    }

private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
    {
        writer.WriteLine(cmd);
        while (stream.Length == 0)
        {
            Thread.Sleep(500);
        }
    }

private StringBuilder ReadStream(StreamReader reader)
    {
        StringBuilder result = new StringBuilder();

        string line;
        while ((line = reader.ReadLine()) != null)
        {
            result.AppendLine(line);
        }
        return result;
    }
person LzyPanda    schedule 17.06.2015
comment
Вы можете легко получить его через пакет NuGet. См. здесь. После этого вам просто нужно добавить его в качестве ссылки. - person LzyPanda; 17.06.2015

Хотя ответ @LzyPanda работает, использование канала оболочки SSH (SshClient.CreateShellStream), пусть только интерактивный терминал, не является хорошей идеей для автоматизации выполнения команд. От этого вы получаете множество побочных эффектов, таких как командные строки, последовательности ANSI, интерактивное поведение некоторых команд и т. Д.

Для автоматизации используйте канал SSH exec (SshClient.CreateCommand):

using (var command = ssh.CreateCommand("command"))
{
    Console.Write(command.Execute());
}

Если вам нужно выполнить несколько команд, повторите приведенный выше код. Вы можете создать любое количество каналов exec для одного SSH-соединения.

Хотя, если команды зависят друг от друга (первая команда изменила среду, например, переменные, которые используются последними командами), вы должны выполнить их в одном канале. Используйте для этого синтаксис оболочки, например && или ;:

using (var command = ssh.CreateCommand("command1 && command2"))
{
    Console.Write(command.Execute());
}

Если вам нужно постоянно читать вывод команд, используйте:

using (var command = ssh.CreateCommand("command"))
{
    var asyncExecute = command.BeginExecute();
    command.OutputStream.CopyTo(Console.OpenStandardOutput());
    command.EndExecute(asyncExecute);
}

Вы также можете использовать ExtendedOutputStream, который содержит как stdout, так и stderr. См. Мониторинг вывода команд SSH.NET в реальном времени.


К сожалению, реализация канала exec в SSH.NET не позволяет вводить команду. В этом случае вам нужно будет прибегнуть к каналу оболочки, пока это ограничение не будет устранено.

person Martin Prikryl    schedule 28.06.2017