Как запускать команды на 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);

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;

Edit: другим подходом было бы использование 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;
    }

в то время как ответ @LzyPanda работает, используя канал SSH "shell" (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 не позволяет доказать ввод команды. Для этого случая использования вам нужно будет прибегнуть к каналу "shell", пока это ограничение не будет решено.