如何在C#中在SSH服务器上运行命令?

23

我需要使用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个回答

34
你可以尝试使用https://github.com/sshnet/SSH.NET,这样你就不需要使用putty或窗口了。你也可以获取响应结果。它的效果类似于这个样子。
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;
    }

14

虽然@LzyPanda的回答是可行的,使用SSH“shell”通道(SshClient.CreateShellStream),更不用说交互式终端,对于自动化命令执行来说并不是一个好主意。您会从中获得很多副作用,例如命令提示符、ANSI序列、某些命令的交互行为等。

对于自动化,请使用SSH“exec”通道(SshClient.CreateCommand):

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

如果您需要执行多个命令,请重复上述代码。您可以为一个SSH连接创建任意数量的“exec”通道。

但是,如果这些命令彼此依赖(例如,第一个命令修改了后续命令使用的环境,例如变量),则必须在一个通道内执行它们。使用shell语法,如&&;

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);
}

您还可以使用包含stderr的ExtendedOutputStream。请参见SSH.NET实时命令输出监控.


不幸的是,在SSH.NET中,“exec”通道的实现不允许提供命令的输入。对于这种情况,您需要使用“shell”通道,直到解决此限制为止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接