Using Renci.SshNet library. I am trying to execute some commands. After executing "command 1", I am executing "command 2" which takes more time.
I am only getting the first line of the output. (reader.ReadToEnd()
is not working in a proper way).
I also tried while (!reader.EndOfStream){ }
with no luck.
I think it is because the delay of the response from server. When there is no response the stream read nothing and finishes.
I found a solution
String tmp;
TimeSpan timeout = new TimeSpan(0, 0, 3);
while ((tmp = s.ReadLine()) != null)
{
Console.WriteLine(tmp);
}
But this is not professional. I need some way in which the stream ends when it ends.
using (var vclient = new SshClient("host", "username", "password"))
{
vclient.Connect();
using (ShellStream shell = vclient.CreateShellStream("dumb", 80, 24, 800, 600, 1024))
{
Console.WriteLine(SendCommand("comand 1", shell));
Console.WriteLine(SendCommand("comand 2", shell));
shell.Close();
}
vclient.Disconnect();
}
public static string SendCommand(string cmd, ShellStream sh)
{
StreamReader reader = null;
try
{
reader = new StreamReader(sh);
StreamWriter writer = new StreamWriter(sh);
writer.AutoFlush = true;
writer.WriteLine(cmd);
while (sh.Length == 0)
{
Thread.Sleep(500);
}
}
catch (Exception ex)
{
Console.WriteLine("exception: " + ex.ToString());
}
return reader.ReadToEnd();
}
The shell is an endless stream. There's no send command – receive output sequence. The ReadToEnd
cannot know where an output of one command ends. All you can do is to read until you yourself can tell that the output ended.
If you cannot tell that, you can help yourself by appending some kind of end-of-output mark like:
command 1 ; echo this-is-the-end-of-the-output
and read until you get "this-is-the-end-of-the-output"
line.
Generally a "shell" channel is not an ideal solution for automation. It's intended for an interactive sessions.
You better use "exec" channel using SshClient.CreateCommand
. With CreateCommand
the channel closes once the command finishes. So there's clear "end of the stream", what makes the ReadToEnd()
work as you expect. And SSH.NET even makes whole command output available in SshCommand.Result
(which internally uses ReadToEnd()
).