Как бы вы транслировали вывод из Process в Rust?

Этот вопрос относится к Rust по состоянию на октябрь 2014 года.

Если вы используете Rust 1.0 или выше, вам лучше поискать решение в другом месте.


У меня есть длительный процесс Rust, который генерирует значения журнала, которые я использую с помощью Process.

Это выглядит, хотя я мог бы периодически "проверять" запущенный процесс, используя set_timeout() а также wait() и сделать что-то вроде цикла высокого уровня, например:

let mut child = match Command::new("thing").arg("...").spawn() {
    Ok(child) => child,
    Err(e) => fail!("failed to execute child: {}", e),
};
loop {
    child.set_timeout(Some(100));
    match child.wait() {
        // ??? Something goes here
    }
}

Вещи, на которых я не на 100%; как определить разницу между ошибкой тайм-аута и ошибкой возврата процесса из wait() и как использовать PipeStream "читать как можно больше, не блокируя поток", каждый интервал для выталкивания.

Это лучший подход? Должен ли я запустить задачу для мониторинга stdout и stderr вместо этого?

2 ответа

Чтобы отличить ошибки от процесса от времени ожидания, вы должны управлять возвратами от ожидания, например здесь:

fn run() {
    let mut child = match Command::new("sleep").arg("1").spawn() {
        Ok(child) => child,
        Err(e) => fail!("failed to execute child: {}", e),
    };
    loop {
        child.set_timeout(Some(1000));
        match child.wait() {
            // Here assume any error is timeout, you can filter from IoErrorKind
            Err(..) => println!("Timeout"),
            Ok(ExitStatus(0)) => {
                println!("Finished without errors");
                return;
            }
            Ok(ExitStatus(a)) => {
                println!("Finished with error number: {}", a);
                return;
            }
            Ok(ExitSignal(a)) => {
                println!("Terminated by signal number: {}", a);
                return;
            }
        }
    }
}

Что касается использования потоков, проверьте с помощью wait_with_output или реализуйте нечто подобное с каналами и потоками: http://doc.rust-lang.org/src/std/home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libstd/io/process.rs.html

Надеюсь, это помогло

Посмотрите в грузовых:

https://docs.rs/cargo-util/0.1.1/cargo_util/struct.ProcessBuilder.html#method.exec_with_streaming

Единственным недостатком является то, что cargo-util, кажется, нуждается в openssl даже с default-features=false... но вы, по крайней мере, можете увидеть, как это делается и read2.

Другие вопросы по тегам