openssh icon indicating copy to clipboard operation
openssh copied to clipboard

Async read of a ssh program stdio.

Open redragonx opened this issue 3 years ago • 14 comments

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?

redragonx avatar Jul 25 '22 18:07 redragonx

How do I know that the ssh program is done?

You need to call RemoteChild::wait.

NobodyXu avatar Jul 26 '22 01:07 NobodyXu

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

while wait is false, read stdio?

redragonx avatar Jul 26 '22 17:07 redragonx

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 avatar Jul 27 '22 02:07 NobodyXu

@redragonx Has your problem been solved by my reply?

NobodyXu avatar Aug 13 '22 07:08 NobodyXu

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?

TaaviE avatar Nov 10 '22 16:11 TaaviE

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 avatar Nov 11 '22 01:11 NobodyXu

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

NobodyXu avatar Nov 11 '22 01:11 NobodyXu

Sorry @NobodyXu

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

redragonx avatar Nov 11 '22 02:11 redragonx

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.

NobodyXu avatar Nov 11 '22 02:11 NobodyXu

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.

TaaviE avatar Nov 11 '22 10:11 TaaviE

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?

NobodyXu avatar Nov 11 '22 14:11 NobodyXu

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.

TaaviE avatar Dec 20 '22 10:12 TaaviE

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 https://github.com/openssh-rust/openssh-mux-client/issues/6 though it has been stale recently, blocking on new release of external dependency tokio-util.

NobodyXu avatar Dec 20 '22 12:12 NobodyXu

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

TaaviE avatar Dec 20 '22 13:12 TaaviE