Подтвердить что ты не робот

Как отправить вывод на stderr?

Один использует это для отправки вывода на стандартный вывод:

println!("some output")

Я думаю, что нет соответствующего макроса, чтобы сделать то же самое для stderr.

4b9b3361

Ответ 1

После ржавчины 1.19

По Rust 1.19 вы можете использовать eprint и eprintln макросы:

fn main() {
    eprintln!("This is going to standard error!, {}", "awesome");
}

Первоначально это было предложено в RFC 1896.

До ржавчины 1.19

Вы можете увидеть реализацию println!, чтобы погрузиться в то, как это работает, но было немного подавляющим, когда я впервые прочитал его.

Вы можете форматировать материал в stderr, используя похожие макросы, хотя:

use std::io::Write;

let name = "world";
writeln!(&mut std::io::stderr(), "Hello {}!", name);

Это даст вам предупреждение unused result which must be used, хотя, поскольку печать для ввода-вывода может завершиться неудачно (об этом мы обычно не думаем при печати!). Мы можем видеть, что существующие методы просто паника в этом случае, поэтому мы можем обновить наш код, чтобы сделать то же самое:

use std::io::Write;

let name = "world";
let r = writeln!(&mut std::io::stderr(), "Hello {}!", name);
r.expect("failed printing to stderr");

Это немного, поэтому верните его в макрос:

use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

fn main() {
    let name = "world";
    println_stderr!("Hello {}!", name)
}

Ответ 2

print! и println! - это удобство методы записи на стандартный вывод. Существуют другие макросы с теми же функциями форматирования, которые доступны для разных задач:

  • write! и writeln!, чтобы написать отформатированная строка в &mut Writer
  • format!, чтобы просто сгенерировать отформатированный String

Чтобы записать в стандартный поток ошибок, вы можете использовать, например. writeln! следующим образом:

use std::io::Write;

fn main() {
    let mut stderr = std::io::stderr();
    writeln!(&mut stderr, "Error!").unwrap();
}

Ответ 3

Сделано так:

use std::io::Write;

fn main() {
    std::io::stderr().write(b"some output\n");
}

Вы можете проверить его, отправив вывод программы в /dev/null, чтобы убедиться, что он работает (я игнорирую предупреждение):

$ rustc foo.rs && ./foo > /dev/null
foo.rs:4:5: 4:42 warning: unused result which must be used, #[warn(unused_must_use)] on by default
foo.rs:4     io::stderr().write(b"some output\n");
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
some output

Аналогично, для stdout можно сделать следующее:

use std::io::Write;

fn main() {
    std::io::stdout().write(b"some output\n");
}

Я думаю, что это означает, что println! - просто удобство: оно короче, а также позволяет некоторое форматирование. В качестве примера последнего отобразится 0x400:

println!("0x{:x}", 1024u)

Ответ 4

Не отвечая на точный вопрос, может быть, интересно, что theres a log crate, который указывает интерфейс для выровненного ведения журнала, который может выполнять другие ящики (например, env_logger).

Результат такого ведения журнала будет отправлен на stderr, и для пользователей есть дополнительные преимущества, такие как указание уровня журнала.

Таким образом, использование такого регистратора может выглядеть так:

#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    error!("this is printed by default");
}

(Пример адаптирован из http://burntsushi.net/rustdoc/env_logger/index.html#example)

Ответ 5

Цель

stderr!("Code {}: Danger, Will Robinson!  Danger!", 42);

Примечания

Другие ответы генерируют неиспользованное предупреждение об импорте с последней ночной, так что вот современный макрос, который Just Works TM.

Код

macro_rules! stderr {
    ($($arg:tt)*) => (
        use std::io::Write;
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr (file handle closed?): {}", x),
        }
    )
}