Syntactic Fructose
Syntactic Fructose

Reputation: 20076

Create child process that duplicates stderr of main process

Is there a stable way I can create a child process that hangs out in the background and inherits stderr, in and out? From what I see, creating a child requires me to launch a separate program. Instead I want to create a child process that lasts as long as the main process, and only serves to allow me to duplicate stderr so I can read from it.

Here's an example of creating a process inside the link

use std::process::Command;

let output = Command::new("sh")
                     .arg("-c")
                     .arg("echo hello")
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
let hello = output.stdout;

what I'd like to do

use std::process::Command;

let leech = Command::new() // create process that hangs out in the background and inherits stderr, stdin and stdout from main process

// ....

// panic occurs somewhere in the program
if thread::panicking {
    output = leech.output().stderr();
}
// screen clears

// print stderr of output

I need to create a leech of sorts because panics being displayed to the main screen are flushed due to terminal graphics. The library will clear the screen which in the process clears away panic messages, If I was able to duplicate stderr and somehow read it, I could reprint the panic message after the terminal restored the pre-program-running state.

Upvotes: 0

Views: 150

Answers (1)

Renato Zannon
Renato Zannon

Reputation: 29941

I believe this is easier to do with a wrapper program, instead of launching something from the rust program itself. Here's an example of how to do it using shell script:

#!/bin/bash

# Redirection magic from http://stackoverflow.com/a/6317938/667984
{ errors=$(./my_rust_program 2>&1 1>&$original_out); } {original_out}>&1

if [[ $? -ne 0 ]]; then
  echo
  echo "--terminal reset shenanigans--"
  echo
  echo "$errors" >&2
fi

When used with this rust program:

fn main() {
    println!("Normal program output");
    panic!("oops");
}

It prints:

Normal program output

--terminal reset shenanigans--

thread '<main>' panicked at 'oops', my_rust_program.rs:3

I believe you can create one in stable rust as well, but since you mention sh in your question I assume you are in a unix environment anyway, and the shell script version should be simpler.

Upvotes: 2

Related Questions