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

Async read of a ssh program stdio. #93

Open
redragonx opened this issue Jul 25, 2022 · 14 comments
Open

Async read of a ssh program stdio. #93

redragonx opened this issue Jul 25, 2022 · 14 comments

Comments

@redragonx
Copy link

How do I go about this the right way? I would like to see an example such that it reads stdio and writes the data to a file in real time.

Here's my current thought process on how I might do the above.

  1. Setup a Command with stdio::piped for stdio, stder and stdin
  2. Spawn the ssh command
  3. get the stdio handles
  4. read the stdio and write to a file stream.
  5. Program exits How do I know that the ssh program is done?
@NobodyXu
Copy link
Member

How do I know that the ssh program is done?

You need to call RemoteChild::wait.

@redragonx
Copy link
Author

is wait meant to be called only once, or can you call it within a loop?

while wait is false, read stdio?

@NobodyXu
Copy link
Member

is wait meant to be called only once

RemoteChild::wait takes RemoteChild by value, so it can be called only once.

Checkout RemoteChild::wait_with_output for example.

Note that you can just use tokio::spawn instead of tokio::try_join, which is more readable and might yield better performance.

@NobodyXu
Copy link
Member

@redragonx Has your problem been solved by my reply?

@TaaviE
Copy link

TaaviE commented Nov 10, 2022

Hopefully I'm not derailing this issue, @NobodyXu. I think I have the same problem, when using tokio::process::Child I can do something like this to handle stdout/stderr/stdin and also potentially wait for the process to end:

loop {
    tokio::select! {
        result = stdout_reader.next_line() => { [...] }
        result = child.wait() => { break; }
    }
}

But when trying to do the same with openssh::child::RemoteChild I can't because wait() function takes ownership of the receiver self, which moves child. What's the intended approach in this case?

@NobodyXu
Copy link
Member

You would have to wrap child in an Option.

And the current implementation has a strange behavior:

If the Child is dropped before stdout/stderr is completely consumed, then the pending data won't be flushed.

This is because Child holds an unix connection to the ssh multiplex server and once it is closed, the ssh multiplex server considers the multiplex session as dead and won't flush any data.

I recommend to just read from stdout until it reaches EOF.

@NobodyXu
Copy link
Member

I can fix this with a breaking change if people really need this.

@redragonx
Copy link
Author

Sorry @NobodyXu

I got distracted with life changes and haven't been to dig into this since then.

@NobodyXu
Copy link
Member

Sorry @NobodyXu

I got distracted with life changes and haven't been to dig into this since then.

No worries, it's open source not coop work, you can do that at any time.

@TaaviE
Copy link

TaaviE commented Nov 11, 2022

You would have to wrap child in an Option.

I'm not really sure how that would be done in this case, sorry.

I recommend to just read from stdout until it reaches EOF.

I'd do that but I pretty much need to handle stdin/stdout/stderr more than once while the process is already running.

@NobodyXu
Copy link
Member

I'd do that but I pretty much need to handle stdin/stdout/stderr more than once while the process is already running.

Maybe you can read in a loop?

@TaaviE
Copy link

TaaviE commented Dec 20, 2022

Maybe you can read in a loop?

Yes, this works to a large extent.

Though I kind-of think that it would be much nicer if one could use the same syntax and semantics for both remote SSH and tokio::process::Child.

@NobodyXu
Copy link
Member

NobodyXu commented Dec 20, 2022

Though I kind-of think that it would be much nicer if one could use the same syntax and semantics for both remote SSH and tokio::process::Child.

It will be fixed by openssh-rust/openssh-mux-client#6 though it has been stale recently, blocking on new release of external dependency tokio-util.

@TaaviE
Copy link

TaaviE commented Dec 20, 2022

That's great to hear, will subscribe to that issue.

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

No branches or pull requests

3 participants