SSH.NET real-time command output monitoring

Egor Okhterov picture Egor Okhterov · Jul 23, 2015 · Viewed 22.1k times · Source

There is a long running script script.sh on a remote Linux machine. I need to start it and monitor it's activity in real time. The script during it's activity may output to stdout and stderr. I am searching for a way to capture both of the streams.

I use Renci SSH.NET to upload script.sh and start it, so it would be great to see a solution bounded to this library. In my mind the perfect solution is the new method:

var realTimeScreen= ...;

var commandExecutionStatus = sshClient.RunCommandAsync(
    command: './script.sh',
    stdoutEventHandler: stdoutString => realTimeScreen.UpdateStdout(stdString)
    stderrEventHandler: stderrString => realTimeScreen.UpdateStderr(stderrString));
...
commandExecutionStatus.ContinueWith(monitoringTask =>
{
    if (monitoringTask.Completed)
    {
        realTimeScreen.Finish();
    }
});

Answer

Martin Prikryl picture Martin Prikryl · Jul 23, 2015

Use SshClient.CreateCommand method. It returns SshCommand instance.

The SshCommand class has ExtendedOutputStream property that returns a stream with both stdout and stderr.

See SshCommandTest.cs:

public void Test_Execute_ExtendedOutputStream()
{
    var host = Resources.HOST;
    var username = Resources.USERNAME;
    var password = Resources.PASSWORD;

    using (var client = new SshClient(host, username, password))
    {
        #region Example SshCommand CreateCommand Execute ExtendedOutputStream

        client.Connect();
        var cmd = client.CreateCommand("echo 12345; echo 654321 >&2");
        var result = cmd.Execute();

        Console.Write(result);

        var reader = new StreamReader(cmd.ExtendedOutputStream);
        Console.WriteLine("DEBUG:");
        Console.Write(reader.ReadToEnd());

        client.Disconnect();

        #endregion

        Assert.Inconclusive();
    }
}

See also a full code for similar WinForms question Execute long time command in SSH.NET and display the results continuously in TextBox.