-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Can't pipe stdout/stderr to the same pipe for a child process #871
Comments
Is there a way to do this? Is this going to get addressed ever? |
This is possible through |
The docs for
If that's true, how can you create two different That is to say:
Will that double close file descriptor Edit: looking at the code, it looks like Stdio's implementation of |
That does seem reasonable, though we should update the docs on If it did close the file descriptors, you could use the libc |
A |
@oconnor663 Thanks for the correction! I failed to see the Explicitly duplicating the descriptor seems like an easy, if platform-specific, approach to making this work properly. However, it would be nice if we could do something like |
@peterhuene for what it's worth there is a |
Hey, maybe reopen this? As @peterhuene said, For example, Python has this - https://docs.python.org/3/library/subprocess.html#subprocess.STDOUT - and it's pretty neat. |
@WGH- if you want to set up pipes yourself, another option is to use the |
@oconnor663 that's a good suggestion, but it still doesn't solve the main problem. You cannot use You can't wrap the other end of the pipe with You can't construct Unless I'm missing something, your only option seems to be to basically duplicate code from here, which is pretty low-level and far from portable: |
Err, sorry, I kind of conflated this with tokio problem. Right, in "vanilla" Rust it's indeed relatively easy to just wrap the other end of the pipe and go from there. |
Is this possible yet? |
For what it's worth. I found a way to get the Here is what I did: let command = r#"bash -c "python3 main.py 2>&1""#;
let mut proc = Command::new("bash")
.arg("-c")
.arg(command)
.stdout(Stdio::piped())
.spawn()
.expect("Failed to execute command");
let mut stdout = proc.stdout.take().unwrap();
//let mut stderr = proc.stdout.take().unwrap();
let mut buffer = String::new();
let _ = stdout.read_to_string(&mut buffer); It pipes bash into bash and then inside that we should specify out command and along with the stderr redirection |
On nightly you can use the #![feature(anonymous_pipe)]
fn main() {
let (reader, writer) = std::io::pipe().unwrap();
let child_stdout = writer.try_clone().unwrap();
let child_stderr = writer;
// some command that outputs to its stdout and stderr
let command = std::process::Command::new("bash")
.args(["-c", r#"echo stdout && echo stderr >&2"#])
.stdout(child_stdout)
.stderr(child_stderr)
.spawn()
.unwrap();
let contents = std::io::read_to_string(reader).unwrap();
dbg!(contents); // "stdout\nstderr\n"
} |
Monday Nov 04, 2013 at 23:24 GMT
For earlier discussion, see rust-lang/rust#10269
This issue was labelled with: A-io in the Rust repository
This is more of a problem with the
rt::io::process
bindings rather than thestd::run
bindings (the latter needs a larger overhaul in general). Thert::io::process
bindings currently don't expose the ability to have something like2>&1
and then you capture the output of&1
(redirecting stderr to stdout and then reading stdout).A possible solution is to add another enum variant to
StdioContainer
named along the lines ofPipeTo(int)
which means that the output of this stdio slot should get redirected to the pipe which was defined at slotint
. Perhaps anIoError
should be raised if it doesn't reference aCreatePipe
slot, perhaps a failure.The text was updated successfully, but these errors were encountered: