Come eseguire i comandi sul server SSH in C #?

Ho bisogno di eseguire questa azione usando un codice C #:

  1. apri putty.exe in background (questo è come una finestra di cmd)
  2. accedi ad un host remoto usando il suo indirizzo IP
  3. inserire un nome utente e una password
  4. eseguire più comandi uno dopo l’altro.
  5. eseguire un altro comando che ottiene una risposta che mi dice che i comandi che ho eseguito prima di quello in cui è stato eseguito correttamente

Quindi sto cercando di farlo in questo modo:

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

Potresti provare https://sshnet.codeplex.com/ . Con questo non avresti bisogno di stucco o di una finestra. Puoi ottenere anche le risposte. Sembrerebbe sth. come questo.

 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; 

Modifica: un altro approccio sarebbe quello di utilizzare uno shellstream.

Creare uno ShellStream una volta come:

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

Quindi puoi usare un comando come questo:

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

Mentre la risposta di @LzyPanda funziona, utilizzando un canale “shell” SSH ( SshClient.CreateShellStream ), lasciare solo un terminale interattivo, non è una buona idea per automatizzare l’esecuzione dei comandi. Si ottengono molti effetti collaterali, come comandi di comando, sequenze ANSI, comportamento interattivo di alcuni comandi, ecc.

Per l’automazione, utilizzare un canale “exec” SSH ( SshClient.CreateCommand ):

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

Se è necessario eseguire più comandi, ripetere il codice sopra. È ansible creare qualsiasi numero di canali “exec” per una connessione SSH.

Sebbene i comandi dipendano l’uno dall’altro (il primo comando ha modificato l’ambiente, ad esempio le variabili, che vengono utilizzati da questi ultimi comandi), li si esegue all’interno di un canale. Usa una syntax di shell per questo, come && o ; :

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

Se hai bisogno di leggere continuamente i comandi in uscita usa:

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

Puoi anche usare ExtendedOutputStream , che contiene sia stdout che stderr. Vedi il monitoraggio dell’uscita di comando in tempo reale SSH.NET .


Purtroppo l’implementazione del canale “exec” in SSH.NET non consente di provare un input al comando. Per quel caso d’uso, dovrai ricorrere al canale “shell”, fino a quando questa limitazione non sarà risolta.