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

[Question] How to read both stderr and stdout? #40

Open
graywolf opened this issue May 3, 2024 · 2 comments
Open

[Question] How to read both stderr and stdout? #40

graywolf opened this issue May 3, 2024 · 2 comments
Assignees
Labels

Comments

@graywolf
Copy link

graywolf commented May 3, 2024

In the documentation I see that I can pick what output I want to read using channel-set-stream!. I can get both by using tr mode, but they are joined into single stream (as documented). I would like to be able to read both, but as separate streams.

It that possible?

My use case is to run remote command, capture the stdout for further processing, but display stderr to the user.

@artyom-poptsov artyom-poptsov added topic/documentation Documentation issues. and removed topic/documentation Documentation issues. labels May 3, 2024
@artyom-poptsov
Copy link
Owner

As Guile-SSH uses libssh under the hood, it inherited some libssh API nuances. Although channel-set-stream! procedure does not directly mapped to any libssh procedure, it changes the data source for the subsequent reads from a channel port. In libssh ssh_channel_read procedure has special boolean paramter is_stderr that allows to specify what stream to read -- it can be stdout (0) or stderr (1), but not both. So when you read a Guile-SSH channel, the data will be requested from the specified stream.

However, I think you can read both stdout and stderr in the following way:

  1. Read all data that you need from a channel using stdout stream (set by default.)
  2. Switch to stderr stream by calling channel-set-stream!.
  3. Read all stderr data from the channel.
  4. Handle stdout and stderr as you wish in your program.

Please check if this algorithm works for you.
-avp

@graywolf
Copy link
Author

graywolf commented May 3, 2024

Yes, this approach does work for me, I reached the same conclusion as you suggested in the mean time. But it only works for "small" data (I think). I am not too versed in the intricacies of ssh protocol, but given the approach above working, there has to be some buffering going on. And those buffers have to be limited in size (if nothing else, by RAM).

So, if we imagine a situation when program keeps writing to both stdout and stderr, I assume it would get stuck sooner or later due to stderr buffer filling up. Is that correct?

To prevent that I believe reading from both at the same time is required, but it seems that is not currently possible. Does it make sense to explore it further? I can imagine some channel-get-stream-ports procedure that would return separate ports for stdout and stderr.

What are your thoughts regarding this?

@artyom-poptsov artyom-poptsov self-assigned this May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants