Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get streaming stdout/stderr and wait for remote process to exit #164

Closed
alanmcgovern opened this issue Feb 8, 2017 · 3 comments · Fixed by #1399
Closed

Cannot get streaming stdout/stderr and wait for remote process to exit #164

alanmcgovern opened this issue Feb 8, 2017 · 3 comments · Fixed by #1399

Comments

@alanmcgovern
Copy link

My scenario is that I want to start a process on a remote machine and wait for it to either crash, or exit gracefully. While I am waiting for it to crash/exit I want to propagate it's stdout/stderr to the host machine so I can parse it, or redirect it to file once I get the data I need from it.

My attempt is: https://gist.github.com/alanmcgovern/c12867f3accc6cf5870d5212d3425974#file-test-cs-L8

The issue with this approach is that the very first (line = reader.ReadLine ()) returns null if you do it 'too quickly'. PipeStream thinks the stream has completed even though the process is still running on the remote machine. If i put a Thread.Sleep before that line I can read some output before i get a null, but eventually i get a null when reading, even though the process hasn't exited.

The only 'reliable' approach to detect when my process exits is to create a ShellStream, then write this command: path/to/long_lived_application; echo TOMBSTONE; and then exit my read-loop when i see the string TOMBSTONE appear in the output.

This approach is here: https://gist.github.com/alanmcgovern/c7bf0fab9760cfcd324573df51c98fbb

Is there a better way to asynchronously run a command and gather it's stdout/stderr?

@drieseng
Copy link
Member

drieseng commented Feb 8, 2017

We've started working on this as part of PR #144, but I got sidetracked by some other issues. I'll soon reboot my work on this.

@alanmcgovern
Copy link
Author

Oh perfect! I'll keep an eye on that PR. If you want to close this immediately feel free, otherwise we can close this when PR #144 is ready :)

@mvdhorst
Copy link

mvdhorst commented Nov 10, 2020

You could also execute the command with extra " 2>&1" so the stderr is also routed to stdout and is readable in the cmd.Result.
You will only get the result when it's finished, but still better than no stderr.
using (var cmd = sshclient.CreateCommand(command + " 2>&1")) { if(timeout > 0) cmd.CommandTimeout = TimeSpan.FromSeconds(timeout); cmd.Execute(); result = cmd.Result; retval = cmd.ExitStatus; //Although the command is within a using statement, this //dispose resolves some internal SSH problems when connecting //to non-existing controllers. cmd.Dispose(); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants